I was wondering how the C++ runtime system detects when an object goes out of scope so that it calls the destructor accordingly to free up the occupied memory.
Thanks.
A variable declared inside a function has a function scope. It has been allocated memory when the function is called and once the function returns something the function execution ends and with it the variable goes out of scope i.e. it gets deleted from the memory.
Any local variable defined within a frame will go out of scope once the program exits that frame. When a stack variable goes out of scope, its destructor is called.
Nothing physical happens. A typical implementation will allocate enough space in the program stack to store all variables at the deepest level of block nesting in the current function. This space is typically allocated in the stack in one shot at the function startup and released back at the function exit.
A destructor is called for a class object when that object passes out of scope or is explicitly deleted.
The runtime doesn't - the compiler keeps tabs on scope and generates the code to call the destructor. If you make a simple test application and look at the generated disassembly you'll see explicit destructor calls.
Disassembly snippet from MSVC:
int main() {
std::string s1;
...
00971416 call dword ptr [__imp_std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (979290h)]
...
{
std::string s2;
00971440 call dword ptr [__imp_std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (979290h)]
...
}
00971452 call dword ptr [__imp_std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (979294h)]
...
}
0097146B call dword ptr [__imp_std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (979294h)]
This is known statically at compile time
{
string s; /* ctor called here */
} /* dtor called here */
Sometimes, it's more difficult
{
again:
{
string s; /* ctor called here */
goto again; /* now dtor of s is called here */
string q; /* ctor not called. not reached. */
} /* dtor of s and q would be called here. but not reached */
}
It has nothing to do with runtime. The compiler keeps track of scope of every lexical variable, and adds destructor calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With