Jagannath
Jagannath

Reputation: 4025

Temporary not getting destructed at the end of the statement

Is this behaviour guaranteed all the time ? The code below creates a char* pointer using temporary unique_ptr. I thought the unique_ptr should get destructed at the end of the statement. To my surprise, the char* still points to valid memory.

void Fill(char* str, long len)
{
    for(int i = 0; i < len; ++i)
        str[i] = 'a';
}

char* x = std::unique_ptr<char[]>(new char[100]).get();

Fill(x, 100);

std::cout << x << std::endl;

Upvotes: 4

Views: 241

Answers (3)

In silico
In silico

Reputation: 52217

That is invoking undefined behavior. Undefined behavior means anything can happen, including having it appear to work. The temporary unique_ptr is in fact being destructed, and as a result deallocates the 100-element char array. You're reading and writing into a memory location that is not allocated to you anymore.

It just so happens that the memory pointed by x hasn't been allocated or read/written for something else by the time you're working with it. But that memory has been already deallocated by the temporary unique_ptr, so you're not supposed to mess with it.

Just do not do this. If you want to keep the array but not the unique_ptr, use release() instead.

Upvotes: 11

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361812

It's true that x points to the allocated memory, but that memory has been deallocated at the end of the statement, and what now x points to is illegal memory, and attempting to use it invokes undefined behaviour.

The program appears to work because the memory has not been allocated to another process. But there is no guarantee that the memory will not be allocated to another process.

Read this best explanation by @Eric Lippert here:

Upvotes: 1

Potatoswatter
Potatoswatter

Reputation: 137960

Since you haven't assigned to a variable of type unique_ptr, you have only created a temporary. The memory is freed as soon as x is initialized, before Fill is called at all.

Simply do this:

std::unique_ptr<char[]> x(new char[100]);

Fill(x.get(), 100);

As the others have said, it's just luck that your program didn't crash. Crashes are seldom guaranteed.

Upvotes: 1

Related Questions