MutomboDikey MutomboDikey - 3 months ago 8
C++ Question

unique pointer memory leak

I was wondering if anyone could help me to sort out a bit of confusion I have with unique pointers. Consider the following code:

// some class "complex" defined here

int main()
{
while(1)
{
unique_ptr<complex> p(new complex[256]);
p.reset();
}
return 1;
}


Now from what I understand, when I invoke
reset()
on the unique pointer it should delete the object that its raw pointer is referring to. In this case, the object happens to be the very first object of type
complex
out of 256 created. Because that's what
new complex[256]
does, am I right? It simply returns a pointer to the first object in the array (which it, of course, also creates)? So the rest of 256 objects should remain untouched.

Following that logic, the infinite loop should create a memory leak, but that does not happen. I am using MS Visual Studio 2013.

What am I missing? I would be very grateful if anyone could fill me in on what's happening here and confirm or disapprove my conjectures

Answer

Your unique_ptr will call delete on the pointer it owns when it goes out of scope. So you're deleting memory allocated by new[] using delete instead of delete[]. That's undefined behavior and it's pretty much pointless to try to reason any further why your code doesn't behave the way you expect it to.

But what might be happening is calling delete on that pointer means only the first complex object in the array is being destroyed (meaning its destructor gets called). The destructor will not be called for the remaining 255 objects, but the memory occupied by the entire array is still freed.

I think your expectation is for your program to use more and more memory and finally die when the new allocation fails, but if the memory occupied by the array is being released, that won't ever happen.


The correct way to handle an array with a unique_ptr is to use the partial specialization for array types

unique_ptr<complex[]> p(new complex[256]);
//                ^^

Or if your standard library implements std::make_unique (C++14), then use

auto p = std::make_unique<complex[]>(256);
Comments