Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the destructor know when to activate itself? Can it be relied upon?

Say for example i have the following code (pure example):

class a {
   int * p;
public:
   a() {
      p = new int;
   }
   ~a() {
      delete p;
   }
};

a * returnnew() {
   a retval;
   return(&retval);
}

int main() {
   a * foo = returnnew();
   return 0;
}

In returnnew(), would retval be destructed after the return of the function (when retval goes out of scope)? Or would it disable automatic destruction after i returned the address and i would be able to say delete foo; at the end of main()? Or, in a similar vein (pseudocode):

void foo(void* arg) {
   bar = (a*)arg;
   //do stuff
   exit_thread();
}

int main() {
   while(true) {
      a asdf;
      create_thread(foo, (void*)&asdf);
   }
   return 0;
}

where would the destructor go? where would i have to say delete? or is this undefined behavior? Would the only possible solution be to use the STL referenced-counted pointers? how would this be implemented?

Thank you- i've used C++ for a while but never quite been in this type of situation, and don't want to create memory leaks.

like image 813
Robert Mason Avatar asked Feb 03 '26 18:02

Robert Mason


1 Answers

For a stack created object, the destructor is automatically called when the object goes out of scope.

For an object created on the heap, the memory will be freed only when you explicitly call delete.

Whether you return the address of a stack created object from a function or not does not matter. The destructor will still be called when the item goes out of scope.

So for your code example:

a * returnnew() 
{
   a retval;
   return(&retval);
}

a's destructor is called before the code jumps back to the code that calls returnnew(). You return the address of that object, but that address is pointing to a place in memory that no longer belongs to you.

Where would i have to say delete?

You only use delete when you used new
You only use delete[] if you used new[]

or is this undefined behavior?

What you do with the address of memory that doesn't belong to you will be undefined behavior. It is not correct code though.

Would the only possible solution be to use the STL referenced-counted pointers?

You could return the object by value, or you could create a new object on the heap. You can also pass in the object to the function via a parameter and ask the function to change it.

how would this be implemented?

//Shows how to fill an object's value by reference
void fillA(a& mya) 
{
   mya.var = 3;
}

//Shows how to return a value on the heap
a* returnNewA() 
{
  //Caller is responsible for deleting the returned pointer.
  return new a();
}

//Shows how to return by value, memory should not be freed, copy will be returned
a returnA() 
{
  return a();
}
like image 165
Brian R. Bondy Avatar answered Feb 06 '26 06:02

Brian R. Bondy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!