Do not call delete this
in the destructor:
5.3.5, Delete: If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will
invoke the destructor (if any) for the object or the elements of the array being deleted.
Therefore, you will have infinite recursion inside the destructor.
Then:
if (p)
delete p;
the check for p
being not null (if (x)
in C++ means if x != 0
) is superfluous. delete
does that check already.
This would be valid:
class Foo {
public:
Foo () : p(0) {}
~Foo() { delete p; }
private:
int *p;
// Handcrafting copy assignment for classes that store
// pointers is seriously non-trivial, so forbid copying:
Foo (Foo const&) = delete;
Foo& operator= (Foo const &) = delete;
};
Do not assume any builtin type, like int
, float
or pointer to something, to be initialized automatically, therefore, do not assume them to be 0
when not explicitly initializing them (only global variables will be zero-initialized):
8.5 Initializers: If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an
object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized
So: Always initialize builtin types!
My question is how should I avoid double delete of a pointer and prevent crash.
Destructors are ought to be entered and left exactly once. Not zero times, not two times, once.
And if you have multiple places that can reach the pointer, but are unsure about when you are allowed to delete, i.e. if you find yourself bookkeeping, use a more trivial algorithm, more trivial rules, or smart-pointers, like std::shared_ptr
or std::unique_ptr
:
class Foo {
public:
Foo (std::shared_ptr<int> tehInt) : tehInt_(tehInt) {}
private:
std::shared_ptr<int> tehInt_;
};
int main() {
std::shared_ptr<int> tehInt;
Foo foo (tehInt);
}