Vincenzo Pii
Vincenzo Pii

Reputation: 19805

Why deleting a pointer to a vector of pointers causes the pointers to be not valid?

EDIT: thank you for the answers! I declared the tellSomething method with a std::string return type while it should have been void!

I was tripping myself up and blamed the poor guiltless delete operator :)!


Let's consider a pointer to a dynamically allocated vector which contains pointers to dynamically allocated objects:

// Create the vector of pointers
std::vector<A *>* v = new std::vector<A *>;

// Create two objects
A *a1 = new A;
A *a2 = new A;

// Populate the vector
v->push_back(a1);
v->push_back(a2);

// Delete the vector
delete v;

// Try accessing one of the objects
a1->tellSomething();    --> // Segmentation fault

As expected, if I delete the vector, the delete on the contained objects is not called (I also verified that A::~A() is never called in the above code), however, the last instruction gives a segmentation fault.

What I expect from the delete v is two things:

But in this case the contained objects are pointers, so no destructor is called.

Also, a1 is not NULL at the end of the listing.

So, why the segmentation fault?


Complete example here: http://ideone.com/r8YC0.


Note: I don't usually use raw pointers with STL containers, please, consider this code as a purely theoretic example to help me understanding the logic of the delete v instruction.

Upvotes: 3

Views: 420

Answers (5)

Matteo Italia
Matteo Italia

Reputation: 126777

The crash you get is completely unrelated; you declared tellSomething as returning a std::string, but you never return anything, so you go into undefined behavior-land; the fact that the program crashed after deallocating the vector is sheer luck, it could have crashed even at the first call to tellSomething.

Fixing that problem makes your program run fine (although you are leaking a1 and a2).

By the way, this teaches you to turn up all the warnings: with -Wall that code would have given you an explicit warning about this potential problem:

matteo@teolapmint ~/cpp $ g++ -Wall testwarns.cpp 
testwarns.cpp: In member function ‘std::string A::tellSomething()’:
testwarns.cpp:12:5: warning: no return statement in function returning non-void [-Wreturn-type]

(just for the record: personally I recommend to compile with -Wall -Wextra -ansi -pedantic, often one warning can save you a lot of debug time).

Upvotes: 9

tumdum
tumdum

Reputation: 2031

It crashes because in linked code in method A::tellSomething you should return std::string which you are not doing. It has nothing to do with deleting v

Upvotes: 3

bames53
bames53

Reputation: 88155

Deleting the vector does not delete the vector elements. You're experiencing a completely different problem caused by tellSomething() failing to return a value when it's specified to return a string.

http://ideone.com/Jo9zi

Upvotes: 3

Luchian Grigore
Luchian Grigore

Reputation: 258548

The crash comes from an attempted call to an invalid std::string destructor:

std::string tellSomething() {
    std::cout << "A!" << std::endl;
}

The call to a1->tellSomething(); tells the runtime to expect an automatic-storage std::string in the scope, which it then attempts to destroy. But that's invalid.

Technically, this is undefined behavior, because you're not returning what you promised you would.

Upvotes: 8

Nate Kohl
Nate Kohl

Reputation: 35914

Your tellSomething method is missing a return value.

Adding a return ""; to that method makes your code run just fine, albeit with memory leaks.

Upvotes: 2

Related Questions