Reputation: 19805
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
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
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
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.
Upvotes: 3
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
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