Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++, allocating space in a for loop, possible memory leak verification

I was just curious as to if this code would create multiple memory leaks, or if it would get cleaned up correctly.

Node *newNode;

for (int i = 0; i < 10; i++)
{
    newNode = new Node();
}

delete newNode;

So obviously the code doesn't do anything, but it does help me explain my scenario. Am I allocating memory 10 times and when I'm deleting the pointer leaving 9 orphans? Or am I reusing the same space being allocated and removing the orphan correctly? Thanks in advance!

like image 483
Xav Avatar asked Mar 14 '13 03:03

Xav


People also ask

When can you tell that a memory leak will occur?

In computer science, a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations in such a way that memory which is no longer needed is not released. A memory leak may also happen when an object is stored in memory but cannot be accessed by the running code.

How are memory leaks caused C?

Memory leaks occur when new memory is allocated dynamically and never deallocated. In C programs, new memory is allocated by the malloc or calloc functions, and deallocated by the free function.

Does C automatically allocate memory?

3.2. 1 Memory Allocation in C Programs The space is allocated once, when your program is started (part of the exec operation), and is never freed. Automatic allocation happens when you declare an automatic variable, such as a function argument or a local variable.


2 Answers

Yeah this is leaking memory. When you do:

newNode = new Node();

You are redefining the pointer to point to newly-allocated memory, in effect losing hold of a way by which to address the previously-pointed to memory in order to delete it.

So when you leave the loop, the newNode pointer points to the last-allocated (tenth) memory/Node. When you delete newNode you are deleting only that memory. You no longer have a way by which to delete the others.

As Zhi Wang pointed out, you can use some form of smart pointer (unique_ptr or shared_ptr in C++11 for example). These smart pointers are basically wrappers around regular pointers which have additional semantics which prevent this kind of leak. If you used one of these, the memory/objects would automatically be deallocated when they went out of scope (upon ending of the current iteration of the for loop in that case).

However, I don't think this would solve your situation in this case. I doubt you want to delete the 10 objects as soon as you create them. Rather, you probably want to store these objects in a container like a std::vector or at the very least have an array of pointers pointing to each of these allocated instances. That way you will have the objects around (which I believe is what you want, since you're constructing them at all) and also have a way by which to remove them later.

like image 103
Jorge Israel Peña Avatar answered Sep 19 '22 00:09

Jorge Israel Peña


Yes, your code leaks memory. Your first guess at the behavior is correct. This code

Node *newNode;

for (int i = 0; i < 10; i++)
{
    newNode = new Node();  // allocate memory 10 times in a loop...
}

delete newNode;            // ... but free the memory only once!

allocates memory 10 times (the new operator inside of the for loop), but frees the memory used by only one of those objects (the delete operator at the bottom). Naturally, this leaves the other 9 objects orphaned—the memory they consume is still allocated, but you now have no way of accessing it to free it. That is, of course, the very definition of a memory leak.

By contrast, this code

Node *newNode;

for (int i = 0; i < 10; i++)
{
    newNode = new Node();    // allocate memory 10 times in a loop
    delete newNode;          // ... and free the memory each time
}

does not leak any memory, because there is one call to delete for each call to new. That's the big rule you have to keep in mind: if you don't match up each call to new with a corresponding call to delete, you will have a memory leak.

Or, perhaps the even better rule when you're working in C++ is never to use raw pointers in the first place. The C++ standard library provides a couple of great wrapper classes that implement the RAII idiom for pointers, which ensures that the objects pointed to get properly destroyed and therefore the memory that they consume gets freed. Start your research either in your favorite C++ book, or on Wikipedia.

like image 30
Cody Gray Avatar answered Sep 21 '22 00:09

Cody Gray