Yesterday I learned an extremely valuable lesson: follow the rule of three.
I think I would have learned it easier, but the error only came on the delete statement. Here was the scenario:
foo.h
class foo{
public:
...
foo(int *Y);
~foo();
int *X;
}
foo.cpp
...
(.. constructor sets X to Y..)
foo:~foo(){
delete [] X;
}
main.cpp
vector<Foo> fooVec;
{ // this is just to demonstrate scope problems more easily.
Y = new int[10000];
(...init Y...)
fooVec.push(Foo(Y)) // I get it: this calls copy constructor, violating rule of three
(...forget to delete Y...)
}
// Y is now out of scope so this is a memory leak
cout << fooVec[0].[X][0] << " " << fooVec[0].[X][1] // THIS WORKS AS INTENDED DUE TO MEMORY LEAK
// program ends, fooVec goes out of scope
which bombs with "pointer being freed has not been allocated"
. I tracked this back to the point where fooVec goes out of scope, which calls foos destructor, which tries to delete X. My main question: Why does the delete actually fail? I never deleted Y in the code (I get this is a memory leak), so I am not actually double deleting a pointer. Moreover, the memory clearly exists, because the cout
line works. If this line had failed I would have figured out the problem much sooner.
Comments below seem to indicate "when Foo(Y)
goes out of scope, X is deleted". But if this is the case, why on Earth does the cout
statement work?
Note: I did not have a copy constructor and assignment overload, hence "rule of three failure". I get that I should have because of the vector push_back statement. I'm asking why exactly not having them killed me here, because I forgot to free Y so I am not actually deleting a pointer twice.
EDIT:
Thank you all for your help. user1158692s answer summed it up, but all the comments in thelambs answer also helped me figure out what exactly was going on, and they stuck around to answer many questions for me. Would accept both if I could..