Reputation: 663
Suppose I have the following snippet.
int main()
{
int num;
int* cost;
while(cin >> num)
{
int sum = 0;
if (num == 0)
break;
// Dynamically allocate the array and set to all zeros
cost = new int [num];
memset(cost, 0, num);
for (int i = 0; i < num; i++)
{
cin >> cost[i];
sum += cost[i];
}
cout << sum/num;
}
` `delete[] cost;
return 0;
}
Although I can move the delete
statement inside the while loop
for my code, for understanding purposes, I want to know what happens with the code as it's written. Does C++ allocate different memory spaces each time I use operator new
?
Does operator delete
only delete the last allocated cost
array?
Upvotes: 20
Views: 1656
Reputation: 254461
Does C++ allocate different memory spaces each time I use operator
new
?
Yes.
Does operator
delete
only delete the last allocatedcost
array?
Yes.
You've lost the only pointers to the others, so they are irrevocably leaked. To avoid this problem, don't juggle pointers, but use RAII to manage dynamic resources automatically. std::vector
would be perfect here (if you actually needed an array at all; your example could just keep reading and re-using a single int
).
Upvotes: 22
Reputation: 320481
There is no cost
array in your code. In your code cost
is a pointer, not an array.
The actual arrays in your code are created by repetitive new int [num]
calls. Each call to new creates a new, independent, nameless array object that lives somewhere in dynamic memory. The new array, once created by new[]
, is accessible through cost
pointer. Since the array is nameless, that cost
pointer is the only link you have that leads to that nameless array created by new[]
. You have no other means to access that nameless array.
And every time you do that cost = new int [num]
in your cycle, you are creating a completely new, different array, breaking the link from cost
to the previous array and making cost
to point to the new one.
Since cost
was your only link to the old array, that old array becomes inaccessible. Access to that old array is lost forever. It is becomes a memory leak.
As you correctly stated it yourself, your delete[]
expression only deallocates the last array - the one cost
ends up pointing to in the end. Of course, this is only true if your code ever executes the cost = new int [num]
line. Note that your cycle might terminate without doing a single allocation, in which case you will apply delete[]
to an uninitialized (garbage) pointer.
Upvotes: 5
Reputation: 8945
I strongly advise you not to use "C idioms" in a C++ program. Let the std
library work for you: that's why it's there. If you want "an array (vector) of n integers," then that's what std::vector
is all about, and it "comes with batteries included." You don't have to monkey-around with things such as "setting a maximum size" or "setting it to zero." You simply work with "this thing," whose inner workings you do not [have to ...] care about, knowing that it has already been thoroughly designed and tested.
Furthermore, when you do this, you're working within C++'s existing framework for memory-management. In particular, you're not doing anything "out-of-band" within your own application "that the standard library doesn't know about, and which might (!!) it up."
C++ gives you a very comprehensive library of fast, efficient, robust, well-tested functionality. Leverage it.
Upvotes: 6
Reputation: 1810
First off this line is wrong:
memset(cost, 0, num);
It assumes an int is only one char long. More typically it's four. You should use something like this if you want to use memset to initialise the array:
memset(cost, 0, num*sizeof(*cost));
Or better yet dump the memset and use this when you allocate the memory:
cost = new int[num]();
As others have pointed out the delete is incorrectly placed and will leak all memory allocated by its corresponding new except for the last. Move it into the loop.
Upvotes: 3
Reputation: 12907
Yes. So you get a memory leak for each iteration of the loop except the last one.
When you use new
, you allocate a new chunk of memory. Assigning the result of the new
to a pointer just changes what this pointer points at. It doesn't automatically release the memory this pointer was referencing before (if there was any).
Upvotes: 3
Reputation: 70929
Every time you allocate new memory for the array, the memory that has been previously allocated is leaked. As a rule of thumb you need to free memory as many times as you have allocated.
Upvotes: 1