Does this cause a memory leak?

In summary: The purpose of unique_ptr, is for it to delete the pointer automatically when it goes out of scope. This happens when the function it was instantiated in exits, or also just if the control flow goes passed the inner most set of curly brackets that it was instantiated in.
  • #1
JonnyG
233
30
I am working through C++ Primer by Lippman et al. In Section 12.2.1 on smart pointers and dynamic arrays, they give this bit of code:

C++:
// up points to an array of ten uninitialized ints
unique_ptr<int[]> up(new int[10]);
up.release(); // automatically uses delete[] to destroy its pointer

I just want to make sure that I am understanding everything properly - doesn't this create a memory leak? The release() method turns the unique pointer, up, into a null pointer but doesn't delete the dynamically allocated array it was pointing at, right? The authors, in the code comments, claims that .release() destroys the pointer. Is this an error on their part or am I missing something?
 
Technology news on Phys.org
  • #2
JonnyG said:
The release() method turns the unique pointer, up, into a null pointer but doesn't delete the dynamically allocated array it was pointing at, right?

The comment on that line of code says it "automatically uses delete[] to destroy its pointer". delete[] frees the memory that was allocated by new.
 
  • #3
PeterDonis said:
The comment on that line of code says it "automatically uses delete[] to destroy its pointer". delete[] frees the memory that was allocated by new.
That is what the comment says but it is not what the C++ documentation seems like to me. It looks like this code uses release incorrectly and does not save the pointer value for a later deletion.
(see http://www.cplusplus.com/reference/memory/unique_ptr/release/ )
CORRECTION: This comment is incorrect. The code uses the smart pointer template which does ensure that a delete is done. I missed that.
 
Last edited:
  • Like
Likes jbunniii
  • #4
If you want to know if you have a memory leak ("do have" and "should have" are not synonyms) I suggest valgrind.
 
  • Like
Likes sysprog
  • #5
Vanadium 50 said:
If you want to know if you have a memory leak ("do have" and "should have" are not synonyms) I suggest valgrind.

Thanks. I need to put aside the time to learn how to use a debugger. Now is probably a good time lol
 
  • #6
FactChecker said:
That is what the comment says but it is not what the C++ documentation seems like to me.

Then, as @Vanadium 50 says, the only way to know for sure is to test it.
 
  • #7
JonnyG said:
I need to put aside the time to learn how to use a debugger.

That is true. But valgrind is not a debugger. It's mostly a memory leak checker, with a few bells and whistles added. You should learn both.
 
  • #8
I think it's a typo. Maybe the author meant reset? Release releases ownership, meaning that the unique_ptr is no longer responsible for managing it. It shouldn't delete it.
 
  • Like
Likes jbunniii and FactChecker
  • #9
PeterDonis said:
Then, as @Vanadium 50 says, the only way to know for sure is to test it.
Right. But I think I'll just take the word of the documentation until someone else tests it and proves it wrong. Since I have not verified that the reference I linked to follows the ISO standards, I can not swear that it is correct, but I would be more likely to think that the compiler is wrong if test results do not follow the documentation.
 
Last edited:
  • #10
C++ causes me to have memory leak!

Sorry guys, I cannot help it! It's funny but it's sad.
 
  • #11
yungman said:
C++ causes me to have memory leak!

Sorry guys, I cannot help it! It's funny but it's sad.
No, C++ allows you to make a memory leak yourself. That is when you allocate memory with new, and don't delete it. This is why most modern C++ programmers almost never manually manage dynamically allocated memory. If you never, ever, give yourself the chance to cause a memory leak, then you will never ever cause a memory leak. This is the main reason to use smart pointers.
 
  • #13
FactChecker said:
I missed that the OP code uses the smart pointer template which does ensure that a delete is done. I missed that in my comments above.
(see https://en.cppreference.com/w/cpp/memory/unique_ptr )
I didn't see anything in there that says release deletes the pointer for that template.
 
  • #14
Jarvis323 said:
I didn't see anything in there that says release deletes the pointer for that template.
I am out of my depth here. I think that the documentation states that the delete of the associated memory occurs automatically when the pointer goes out of scope. I am not sure exactly when that happens.
 
  • #15
FactChecker said:
I am out of my depth here. I think that the documentation states that the delete of the associated memory occurs automatically when the pointer goes out of scope. I am not sure exactly when that happens.
The purpose of unique_ptr, is for it to delete the pointer automatically when it goes out of scope. This happens when the function it was instantiated in exits, or also just if the control flow goes passed the inner most set of curly brackets that it was instantiated in.

Here is an example. I gave the objects ids according to the order they were created. And when they are destroyed (the destructor is called when a pointer to an object is deleted) it prints that out.

C:
#include <memory>
#include <iostream>

struct S {
    static int nextId;
    int id;
    S() {  id = nextId++; }
    ~S() { std::cout << "instance " << id << " destroyed" << std::endl; }
};
int S::nextId = 0;

int main() {

    std::unique_ptr< S[] > a( new S[ 1 ] ); // id 0
    S * ar = a.release();

    std::unique_ptr< S[] > b( new S[ 1 ] ); // id 1

    {
       std::unique_ptr< S[] > c( new S[ 1 ] ); // id 2
    } // c goes out of scope here

    return 0;
} // a, b go out of scope here,
// and both a and b are destroyed.
// But the object managed by a (instance 0) is not deleted
// because it was released from a's ownership.

Output:

Code:
instance 2 destroyed
instance 1 destroyed
 
Last edited:
  • Like
  • Informative
Likes jtbell and FactChecker
  • #16
Basically, in higher level languages like Java and C#, they don't let you manually allocate and delete memory. Instead, they use reference counting and garbage collection. In those languages, whenever all references to an object have gone out of scope, the object is flagged as garbage to be collected at some later time.

In C, C++, people tend to make mistakes and forget to delete something after they've created it. People make mistakes, and mistakes can make memory leaks. So they created smart pointers as a way for people to achieve the same level of safety as automatic memory management in those higher level languages. unique_ptr is just a single object managing the pointer. shared_ptr is like reference counting, in that you can have many shared pointers jointly managing the same dynamic memory, which will be deleted only when all of the shared pointers have gone out of scope.

The difference between smart pointers in C++ and automatic memory management in Java, for example, is that in C++ the memory is freed immediately after the managing smart pointers go out of scope, whereas in Java, the garbage collector will just run at some unknown time in the future and delete a bunch of piled up garbage at once. They both have some advantages, because Java could theoretically hold off on deleting until a more appropriate time through some kind of automatic optimization. But in C++, you the programmer knows/controls when things are deleted. I prefer the C++ way personally. That said, I don't find myself using shared_pointers, only unique_ptr sometimes. Basically, I almost never explicitly delete anything though.
 
  • Informative
  • Like
Likes sysprog and FactChecker
  • #17
Sorry for taking a while to get reply back here. This weekend was very busy for me. Anyway, I can confirm that the program does leak memory. I used a memory checker for Windows called dr memory.
 
  • #18
Jarvis323 said:
In C, C++, people tend to make mistakes and forget to delete something after they've created it.

I see this more in C++ than C, and I think it is not so much forgetting but not working through the logic.

(1) Why C++? Because in cases where it would be natural to pass a function an object, call-by-value requires passing a pointer. I don't want to start a holy war on value vs. reference - this is just descriptive.

(2) How do these errors come about? It's not because the programmer somehow forgot that new and delete come in pairs. Where I have seen it most often - including in my own code - is that the delete is in the wrong place. The program crashes when it tries to free something that doesn't exist. The programmer looks at it and says "Oh, of course, it belongs over here" and moves it. But the new spot is nor always right either: sometimes instead of deleting too much, it deletes too little. And the leak is born.
 
  • #19
Vanadium 50 said:
I see this more in C++ than C, and I think it is not so much forgetting but not working through the logic.

(1) Why C++? Because in cases where it would be natural to pass a function an object, call-by-value requires passing a pointer. I don't want to start a holy war on value vs. reference - this is just descriptive.

(2) How do these errors come about? It's not because the programmer somehow forgot that new and delete come in pairs. Where I have seen it most often - including in my own code - is that the delete is in the wrong place. The program crashes when it tries to free something that doesn't exist. The programmer looks at it and says "Oh, of course, it belongs over here" and moves it. But the new spot is nor always right either: sometimes instead of deleting too much, it deletes too little. And the leak is born.
I suppose this might be true to some extent/in some cases. The thing with C++ is that you have so much freedom. So even if there is a 100% safe set of rules/features/idioms to follow to prevent memory bugs, they are still only optional, and not necessarily trivial, and you can't expect everyone working on a project to follow them.
 
Last edited:
  • #20
As Bjarne Stroustrup once said, "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off."
 

1. Does using too much memory cause a memory leak?

No, using too much memory does not necessarily cause a memory leak. A memory leak is caused by a program not properly releasing memory that is no longer needed.

2. Can a memory leak cause a computer to crash?

Yes, if a memory leak is severe enough, it can cause a computer to crash. This is because the program is using up all available memory, leaving none for other processes.

3. How do I know if my program has a memory leak?

You can use debugging tools, such as memory profilers, to track memory usage and identify any potential memory leaks. You can also monitor system resources to see if memory usage is increasing over time.

4. Can a memory leak be fixed?

Yes, memory leaks can be fixed by identifying and addressing the root cause in the code. This may involve implementing proper memory management techniques and fixing any bugs that are causing the memory leak.

5. Are memory leaks only a problem in older programming languages?

No, memory leaks can occur in any programming language if the code is not properly managed. However, some newer languages have built-in memory management systems that make it easier to prevent memory leaks.

Similar threads

  • Programming and Computer Science
Replies
17
Views
1K
  • Programming and Computer Science
Replies
3
Views
1K
  • Programming and Computer Science
Replies
4
Views
3K
  • Programming and Computer Science
Replies
23
Views
1K
  • Programming and Computer Science
Replies
17
Views
2K
  • Programming and Computer Science
Replies
8
Views
4K
  • Programming and Computer Science
Replies
4
Views
1K
  • Programming and Computer Science
Replies
10
Views
6K
  • Programming and Computer Science
Replies
4
Views
2K
  • General Engineering
Replies
1
Views
4K
Back
Top