0

I have function I wrote in some class. I don't understand why when I create object named: Square square; a d'tor of Square is being called when exiting the function. While when I create the object as: Square* square = new Square(); no d'tor is being called.

There is no inheritance at all on the classes.

Here an example for the function in a two versions:

//=======Enter to d'tor in the end of the function to ~Square==========
void DrawShapesApp::addSquare()
{
    int row, col;
    int edge;
    char ch;

    Square square;

    getSquareInfo(row, col, edge, ch);
    square.setAll(row, col, edge, ch);
    m_squares.push_back(&square);
}





//=======Doesn't enter to d'tor in the end of the function==========
void DrawShapesApp::addSquare()
{
    int row, col;
    int edge;
    char ch;
    Square* square = new Square();

    getSquareInfo(row, col, edge, ch);
        (*square).setAll(row, col, edge, ch);
    m_squares.push_back(&square);
}
masoud
  • 55,379
  • 16
  • 141
  • 208
E235
  • 11,560
  • 24
  • 91
  • 141
  • 2
    You tagged this as C#,C++ and C. I'm assuming this is a C++ problem from the syntax? – Haedrian Mar 23 '13 at 21:23
  • If you only change `vector m_squares;` to `vector m_squares;` then all your problems will go away. Don't use pointers, especially not in STL classes. – john Mar 23 '13 at 21:38

4 Answers4

2

When you create an object with "new", you are responsible for deleting it. This is done with "delete":

delete square;

In your second function you have a memory leak -- the object is never destroyed and the memory is never freed.

svk
  • 5,854
  • 17
  • 22
1
Square* square = new Square();

This is a definition of a Square* with automatic storage duration. That pointer is destroyed automatically at the end of the function.

However, the pointer is initialized with the result of new Square(). This new-expression creates an object of type Square with dynamic storage duration. That object is not destroyed at the end of the function.

To destroy an object with dynamic storage duration, you must call delete on a pointer to that object. In this case, do:

delete square;

If you do not destroy the object manually, you will have a memory leak.

However, it is common in modern C++ to have your dynamically allocated objects managed by a smart pointer that will handle the delete for you:

std::unique_ptr<Square> square(new Square());
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
1

An object created this way:

Square square;

Is said to have automatic storage duration, and will be destroyed automatically when it goes out of scope. For instance:

void foo()
{
    Square square1;
    {
        Square square2;
    } // Here square2 will be destroyed

    if (cond) { /* .... */ }
    else
    {
        Square square3;
        // ...
    } // Here square3 will be destroyed
    // ...
} // Here square1 will be destroyed

You usually choose to instantiate objects this way if you do not need/want them to survive the end of their scope (although one could argue that moving objects in C++11 provides a way of achieving this also for objects with automatic storage duration).

An object created this way, on the other hand:

Square* pSquare = new Square();

Is said to have dynamic storage duration, and will be destroyed when delete will be invoked for a pointer to that object:

delete pSquare;

In this case, you have the responsibility of manually destroying the object, and failing to do so for every object allocated with new will cause a memory leak. For instance:

void foo()
{
    Square* pSquare1 = new Square();
    Square* pSquare2 = nullptr;
    if (/* ... */)
    {
        pSquare2 = new Square();
    }

    delete pSquare2; // Here the object pointed to by pSquare2 is destroyed
} // Whoops! I forgot deleting the object pointed to by pSquare1, that's a leak!

You normally choose to create objects this way if you want them to live beyond the end of their scope, and/or if you need reference semantics.

Community
  • 1
  • 1
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
0

When you declare an object like this

Square square;

It will be destroyed after going out of declaration scope, automatically.

And...

When you declare an object like this

Square *square = new Square();

It will be destroyed after delete. You must explicitly delete the object.

masoud
  • 55,379
  • 16
  • 141
  • 208