morz wrote:
i just search for a while in c++ groups but cannot find good answer.
i have code like this:
int **ptr;
ptr = new char *[2];
ptr[0] = new int(5);
ptr[1] = new int(16);
i know we can delete ptr like this:
for (int i = 0; i <2; i++)
delete ptr[i];
delete ptr;
Correct.
But can i delete like this? :
delete ptr;
for (int i = 0; i <2; i++)
delete ptr[i];
No, you cannot: Within the for loop you are dereferencing the previously
deleted pointer ptr. The expression ptr[i] does that! Dereferencing a
deleted pointer is undefined behavior. This kind of undefined behavior can
be quite nasty a bug since very often it manifests itself in expected
behavior most of the time and explodes into your face only occasionally.
or
can somebody give any other ways or sample?
P/S: i just like master in deep about pointer
The deep mastery of pointers is knowing all the tools that allow you *not*
to use pointers in the first place. Pointers involve all sorts of nasty
pitfalls: double deletion, dereferencing after deletion, missing deletion
(aka memory leak) to name just those inherently steming from pointer use.
The problem here is that pointer management involves life time management
and is intrinsically a problem that tends to spread out over your code. The
general advice here would be to have well defined ownership (each pointer
is owned by a single object and allocation as well as deletion is the
responsibility of that object). The best idiom for that would be to confine
allocation of pointers to constructors and to put the corresponding
deallocation within the destructor.
Then there is the whole area of traps that come from the interaction of
dynamic memory allocation and stack unwinding triggered by exceptions. Let
me just give you the simplest example:
{
SomeType* some_pointer = new SomeType( some arguments );
// some code
...
delete some_pointer;
}
What happens if the code between the allocation and the delete throws an
exception and the program starts stack unwinding? The delete statement will
never be reached. However, the destructor for some_pointer will be called
and the variable will be gone: you can never make up for the missing
delete. BTW: if you look close enough you will find that the second
allocation in your program may serve as the "some code" section from this
example. In other words, your sample snippet exhibits a possible memory
leak if the second allocation fails.
Avoid pointers whenever possible. There are lots of tools that allow you to
get away without touching raw pointers most of the time: shared_ptr<T>,
auto_ptr<T>, and of course all the standard containers like std::map and
std::vector from the standard library.
Best
Kai-Uwe Bux