np-hard
np-hard

Reputation: 5815

stl vector memory management

I am using borland 2006 c++, and have following code. I am using vectors, and have trouble understanding why the destructor is not being called.

basically i have a class A

class A
{
private:
    TObjectList* list;
    int myid;
public:
 __fastcall A(int);
 __fastcall ~A();
};

__fastcall A::A(int num)
{
    myid = num;
    list = new TObjectList();

}

__fastcall A::~A()
{
    delete list;
}

int main(int argc, char* argv[])
{
    myfunc();
    return 0;
}

void myfunc()
{
    vector<A*> vec;
    vec.push_back(new A(1));
    vec.push_back(new A(2));
}

according to what i read, when variable vec goes out of scope in myfunc(), it should destruct its contained elements, so the destructor for A should be called. I have a breakpoint at ~A(), but never gets called, i have tried resize(), erase methods also

TIA

Upvotes: 1

Views: 2548

Answers (4)

Mark Ransom
Mark Ransom

Reputation: 308530

Lots of good answers already, but I'll add one more:

Use boost::ptr_vector from the Boost Pointer Container Library, instead of std::vector. It will delete the objects when the vector goes out of scope, thus calling the destructors.

Upvotes: 3

David Thornley
David Thornley

Reputation: 57076

Grab the Boost libraries, and wherever you have a raw pointer in the above you use boost::shared_ptr<> instead. (Well, not in the signature of main().)

Upvotes: 1

rlbond
rlbond

Reputation: 67847

The destructor for A isn't called because you don't have a vector of A. You have a vector of pointers to A, and the destructors for the pointers are called. Pointers don't have a destructor, so nothing happens.

One way to delete everything would be to manually do something like

while (!vec.empty())
{
    delete vec.back();
    vec.pop_back();
}

Upvotes: 3

David Seiler
David Seiler

Reputation: 9725

vec does destruct its elements when it goes out of scope. The problem here is that vec's elements are the pointers to A objects, not A objects themselves. If you instead did

vector<A> vec;
vec.push_back(A(1));
vec.push_back(A(2));

...then things would work as you expect.

ETA: note, though, that if you do this you have to define a copy constructor for A. That should involve doing a deep copy of the TObjectList member. Otherwise, when you copy an A object you'll wind up with two objects both pointing to the same TObjectList, and your program will crash when the second object is destroyed.

Upvotes: 15

Related Questions