5

Assume a class called Vec exists with a vector called arr as it's only member . The following code does NOT leak memory. (Which means my destructor for Vec is working as expected.)

int main() {
    Vec *obj = new Vec(5); // initializes a vector of size 5
    delete obj;
}

However, in the following code, there is a memory leak. But why? I seem to have a delete for each use of new. What am I missing?

int main() {
    Vec* obj;
    obj = new Vec(5);

    if (true) {
        delete obj;
        Vec* obj = new Vec(6);
    }

    delete obj;
}

PS: I checked for memory leak using valgrind.

babrar
  • 159
  • 10

4 Answers4

10

Scope.

Vec* obj = new Vec(6); makes a new variable named obj that only exists within the if's body and hides the obj at the outer scope. The inner obj goes out of scope and vanishes at the end of the if's body, taking the last pointer to that new allocation with it. The code then re-deletes the obj at the outer scope (not a good thing to do).

Solution:

int main() {
    Vec* obj;
    obj = new Vec(5);

    if (true) {
        delete obj;
        obj = new Vec(6); // re-uses the original obj
    }

    delete obj;
}
user4581301
  • 29,019
  • 5
  • 26
  • 45
  • "taking the last pointer to that new allocation with it" - However, If I do a ```cout << obj->arr.size();``` right before the last `delete obj;` I get `6`. Why is that? Why am I getting back the attribute of the shadowed variable outside the scope? – babrar Feb 13 '20 at 04:04
  • 3
    @babrar Because the behavior when dereferencing dangling pointer is undefined. In this case, the implementation likely just so happened to re-use the same memory for both `Vec` objects. – Miles Budnek Feb 13 '20 at 04:07
2

The Vec* obj declared inside the if condition is in another scope. You are doing another delete outside the scope that is pointing to the Vec* object you declared at the beginning of the main(). Hence that Vec array allocated inside if condition is your memory leak

FahimAhmed
  • 422
  • 1
  • 12
1

When you say Vec* obj = again, instead of just obj =, you shadow the old variable, instead of updating it. As a result, you leak the second obj, and worse, you double-free the first one.

1

Removing the "Vec*" in the conditional statement will fix the memory leak. You are defining a new pointer of type Vec (which happens to also be called obj) inside the conditional and never freeing that memory. Both "delete"s reference the first "obj" as the second "obj" goes out of scope without being deleted at the end of the conditional.

Mason W
  • 81
  • 3