3

As a C++ neophyte trying to understand smart pointers. I have written below code to check.

It did compile and run but I was expecting the destructor of my class to be invoked and print the cout's from the destructor but it didn't .

Do we need to overload any function in the user defined class so that its destructor is called when the smart_ptr object of that class gets destroyed.

Why is that it did not invoke the object destructor. What is that i am missing?

#include <iostream>
#include <cstdlib>
#include <tr1/memory> 
#include <string>

//using namespace std;

class myclass
{
public:
  myclass();
  myclass(int);
  ~myclass();
private:
  int *ptr;
  std::string *cptr;
};

myclass::myclass()
{
    std::cout << "Inside default constructor\n";
}

myclass::myclass(int a)
{
   std::cout << "Inside user defined constructor\n" ;
   ptr = new int[10];
   cptr = new std::string("AD");
}

myclass::~myclass()
{
    std::cout << "Inside destructor..\n";
    delete [] ptr;
    delete cptr;

    std::cout << "Freed memory..\n";
}

int main()
{


   int i;
   std::cin >> i;       
 std::tr1::shared_ptr<std::string> smartstr(new std::string);
 std::tr1::shared_ptr<myclass> smart_a(new myclass(i));
   if(i == 0)
   {
      std::cout << "Exiting...\n";
      exit(-1);
   }


}
goldenmean
  • 18,376
  • 54
  • 154
  • 211
  • Did you exit, or just allow `main` to return? Does it behave the same in both cases? – Useless Jun 17 '13 at 14:12
  • 1
    I thought I'd give goldenmean a chance to spot the difference :) – Useless Jun 17 '13 at 14:17
  • @Useless: I went down the exit(-1) path. But I get the point from the answers below. – goldenmean Jun 17 '13 at 14:22
  • For completeness, you should replace the call to `exit()` with an exception `throw`. Then you will see the destructor gets called. – juanchopanza Jun 17 '13 at 14:30
  • @juanchopanza - Yes thanks. Will ensure that aspect of the question i had - resource freeing on exceptions. – goldenmean Jun 17 '13 at 14:37
  • 1
    @juanchopanza: You'll also need to handle the exception to be sure that the stack is unwound. – Mike Seymour Jun 17 '13 at 15:25
  • @Mike Seymour - So one would need a try{ ... throw ; }catch(){...}. IS it correct? any specific things needed to be done while 'catching' the exception. – goldenmean Jun 18 '13 at 09:16
  • @goldenmean: You don't need to do anything specific apart from catching it (and not rethrowing). It the exception isn't handled, then `std::terminate` is called; and it's implementation-defined whether or not the stack is unwound (destroying the local variables) first. – Mike Seymour Jun 18 '13 at 10:12

4 Answers4

11

The reason the object is never destroyed is because you are exiting the program by calling exit. This causes the program to exit before the smart pointer objects have a chance to go out of scope thus the objects they manage are never destroyed. Since you are in main use a return statement instead of calling exit.

Captain Obvlious
  • 19,754
  • 5
  • 44
  • 74
4

And, as additional information to other answers, note from the Standard:

Per §3.6.1/4:

Terminating the program without leaving the current block (e.g., by calling the function std::exit(int) (18.5)) does not destroy any objects with automatic storage duration (12.4).

awesoon
  • 32,469
  • 11
  • 74
  • 99
2

In the code below,

if(i == 0)
{
   std::cout << "Exiting...\n";
   exit(-1);
}

You are terminating the program by calling exit(), so the object is never destroyed. So remove the exit(-1); from the code.

Deepu
  • 7,592
  • 4
  • 25
  • 47
-1

One possible solution is ensure that your buffer is flushed in your destructor. Use std::endl; in your destructor. For more information, please look here: Buffer Flushing, Stack Overflow

Community
  • 1
  • 1
Tyler Jandreau
  • 4,245
  • 1
  • 22
  • 47