Julio Corzo
Julio Corzo

Reputation: 399

C++ Dangling Pointers and Memory Leaks

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.

  1. 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.
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = ptrA;
  1. I'm guessing that this is a dangling pointer because 345 was deallocated from memory, so ptrB points to nothing.
ptrA = new int;
*ptrA = 345;
ptrB = ptrA;
delete ptrA;
  1. This is where I'm complete lost. Does the last line mean that the pointer is pointing to another pointer? Not sure what the implications of this would be.
ptrA = new int;
ptrB = new int;
*ptrA = 345;
*ptrB = *ptrA;
  1. Like the previous question, I'm not sure what pointing to a pointer means, or if I even understand what this is achieving.
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = new int;
*ptrB = *ptrA;
  1. 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?
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

Answers (4)

Loki Astari
Loki Astari

Reputation: 264381

The rules of the game:

  • For every new Type draw a box. Put a question in the box (you don't know what is in there).
  • For every delete p cross out the box pointed to by p.
  • For every a = b (where there are no stars) draw a line from variable a to a box b.
  • For every *x = y write y inside the box pointed at by x.
  • For every *x = *y read the content of the box y and put a copy in x

The result:

  • When you have a box with no variables pointing at it you have a leak.
  • If you have a pointer that does not point at a box (or a crossed out box) you have a dangling pointer.

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

Kunal Puri
Kunal Puri

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

Michel Keijzers
Michel Keijzers

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

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385104

  1. 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.

  1. I'm guessing that this is a dangling pointer because 345 was deallocated from memory, so ptrB points to nothing.

Correct.

  1. 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.

  1. 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.

  1. 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

Related Questions