问题
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!
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/15400747/c-allocating-space-in-a-for-loop-possible-memory-leak-verification