Reputation: 23
I'm relatively new to C++ and I want to understand memory management and pointers at the same time.
Let's say I have the code below
int* p1;
int* p2;
int* p3 = new int[some size];
p1 = p3;
std::swap(p1,p2);
How do I properly delete the dynamically allocated memory? Is doing delete[] p3
enough? Should I delete p2
too after that?
Upvotes: 2
Views: 407
Reputation: 47
To understand what is happening here, it would help to add some debug statements, i.e:
std::cout << p1 << " " << p2 << " " << p3 << "\n";
The trace will result in an output like:
0 0 0x15e7eb0
0x15e7eb0 0 0x15e7eb0
0 0x15e7eb0 0x15e7eb0
(Note that I initialized p1 and p1 to nullptr
)
p3 initially points to some memory. After the assignment p1 = p3
, p1 now points to the same memory address as p3. When you swap the pointers, now it's p2 that points to the same memory address as p3.
There are a couple of things to note here:
delete[]
with the corresponding new[]
(do not call delete
with new[]
and so forth)As you can see, dealing with raw pointers and memory allocation can easily lead to pitfalls. It's generally recommended to use smart pointers, or if you have a non-owning pointer, to use abstractions like observer_ptr
to clearly indicate the pointer's purpose in the code.
Upvotes: 1
Reputation: 122994
There is some fuzzyness in colloquial speech when you do something like this:
delete x;
We say "we delete x
". Strictly speaking thats wrong, because what is deleted is the object pointed to by x
.
Every object allocated via new
/new[]
must be destroyed via one call to delete
/delete[]
. Whether you have two or more pointers to the same object does not change that.
int* p1 = nullptr;
int* p2 = nullptr;
int* p3 = new int[some size]; // p3 points to the array
p1 = p3; // p1 points to the same array
std::swap(p1,p2); // now p1 == nullptr, p2 points to the array
Note that the pointers are uninitialized in your example. Reading their values causes undefined behavior. As this isnt the crux of the question I avoided that by initializing them.
There is one array created via new []
and it is that one array that you have to delete via delete []
. You may not delete it twice. So either call delete[] p3;
or delete[] p2;
, but not both.
PS: Comments already mentioned smart pointers and I also suggest you to read about them. Nowadays you should not use raw owning pointers. An owning pointer is one that you need to call delete
on, it "owns" the pointed to object. Raw pointers should only be used to "observe", ie you should never need to worry about calling delete
(or delete[]
) on a raw pointer. Of course you still need to take care whether the pointed to object is still alive, but that is not specific to dynamic allocation:
int* p;
{
int x = 42;
p = &x; // p points to x;
} // x goes out of scope
// here p is not a valid pointer anymore
Upvotes: 2