Reputation: 399
I'm having a hard time understanding how to tell between dangling pointers and memory leaks. I have a few questions on a recent assignment that are puzzling me, and after reading into it, I am still puzzled. I don't want someone to do my homework for me, I want to be able to understand why something is what it is, if that makes sense.
So, the homework:
Given the declarations:
int *ptrA, *ptrB;
Tell whether each code segment below results in a memory leak, a dangling pointer, or neither. Draw pictures to help.
ptrA
is already pointing to something in memory, so this one is neither a dangling pointer or a memory leak.ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = ptrA;
ptrB
points to nothing.ptrA = new int;
*ptrA = 345;
ptrB = ptrA;
delete ptrA;
ptrA = new int;
ptrB = new int;
*ptrA = 345;
*ptrB = *ptrA;
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = new int;
*ptrB = *ptrA;
ptrA = LocationOfAge();
where function LocationOfAge
is defined as:
int *LocationOfAge() {
int age = 21;
return &age;
}
Thanks for anyone willing to help.
Upvotes: 4
Views: 2379
Reputation: 264381
The rules of the game:
new Type
draw a box. Put a question in the box (you don't know what is in there).delete p
cross out the box pointed to by p
.a = b
(where there are no stars) draw a line from variable a
to a box b
.*x = y
write y
inside the box pointed at by x
.*x = *y
read the content of the box y
and put a copy in x
The result:
The first problem:
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = ptrA;
Lets do this line by line:
ptrA = new int;
// Part 1 has a new so draw a box
*********
* ? *
*********
// Part 2 assignment to variable add a line
ptrA -------> *********
* ? *
*********
ptrB = new int;
// Part 3 has a new so draw another box
ptrA -------> *********
* ? *
*********
*********
* ? *
*********
// Part 4 assignment to variable add a line
ptrA -------> *********
* ? *
*********
ptrB -------> *********
* ? *
*********
*ptrA = 345;
ptrA -------> *********
* 345 *
*********
ptrB -------> *********
* ? *
*********
ptrB = ptrA;
ptrA -------> *********
| * 345 *
| *********
|
ptrB ---- *********
* ? *
*********
Seems like you have a leaked box. i.e. There is a box with no variable pointing at it.
Upvotes: 15
Reputation: 3427
Let's take one question at a time.
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = ptrA;
Here, it is a memory leak. Why? Because there is no delete
first of all. Secondly, when you do ptrB = ptrA;
, there is practically no way to call delete
for the object that was pointed to by ptrB
earlier.
ptrA = new int;
*ptrA = 345;
ptrB = ptrA;
delete ptrA;
This is an example of dangling pointer. Once delete
is called on ptrA, the object pointed to by ptrA gets deallocated. So, ptrB points to a deallocated location whose behaviour is undefined. So, Dangling pointer!
ptrA = new int;
ptrB = new int;
*ptrA = 345;
*ptrB = *ptrA;
Here, there is memory leak simply because we are not calling delete
. What we are doing is that we are creating two objects which are pointed by ptrA and ptrB respectively and both objects have value of 345. They still hold space in the heap. But how come both have the value of 345? Simple.
When you did *ptrA = 345;
, it meant that the value of the object pointed to by ptrA should be set to 345.
When you did *ptrB = *ptrA;
, it meant that the value of the object pointed by ptrB should be assigned with the value of the object pointed by ptrA.
This is the simple functioning of dereferencing operator.
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = new int;
*ptrB = *ptrA;
This is similar to first one. In line 2, ptrB pointed to a dynamically allocated object. After execution of Line 4, ptrB points to entirely new object. So, there is no way to deallocate the object whose memory was allocated at line 2. So, Memory Leak!
int *LocationOfAge() {
int age = 21;
return &age;
}
Here, age
is a local variable which will die once the function ends. So, any pointer to that local variable leads to undefined behaviour. So, Dangling Pointer!
Upvotes: 0
Reputation: 15357
To prevent making all homework, your first assumption is wrong.
1. ptrA = new int;
2. ptrB = new int;
3. *ptrA = 345;
4. ptrB = ptrA;
In line 1, ptrA creates a new integer (bytes are allocated), in line 2 ptrB allocates bytes. Than in 3, the memory allocated in 1 is filled, which is OK. However, in line 4, ptrB is overwritten with the address of 3, this means the original addres of ptrB is not reachable anymore. And thus there is a memory leak, because the bytes allocated for the integer PtrB by line 2 can never be accessed anymore, since there is no pointer pointing to it.
It's much easier if you write a drawing, by using arrows for pointers and a box with either a ? for a declaration and a specific value when filled in. So it would look like:
1. ptrA -> [ ? ]
2. ptrA -> [ ? ], ptrB -> [ ? ]
3. ptrA -> [ 345 ], ptrB -> [ ? ]
4. ptrA -> [ 345 ] <- ptrB, [ ? ]
As you can see, the last box [ ? ] does not have any pointer pointing to it.
Upvotes: 0
Reputation: 385104
- I'm guessing that this is fine, as ptrA is already pointing to something in memory, so this one is neither a dangling pointer or a memory leak.
Yeah but now ptrB
points to it too, and you have no way of freeing the thing that ptrB
pointed to before.
So that's a leak.
- I'm guessing that this is a dangling pointer because 345 was deallocated from memory, so ptrB points to nothing.
Correct.
- Does the last line mean that the pointer is pointing to another pointer?
No, it gives <the thing that ptrB
points to> the value of <the thing that ptrA
points to>. No changes to the pointers involved, only int
assignment.
- Like the previous question, I'm not sure what pointing to a pointer means, or if I even understand what this is achieving.
The second new int
is leaked, because the thing that used to point to it (ptrB
) now points to a third new int
and the former can no longer be freed.
- I know this is a dangling pointer, but I don't know why. Is it because the pointer is pointing to a local variable that went out of scope when the function finished?
Yes.
Upvotes: 0