Временно не разрушается в конце заявления - PullRequest
4 голосов
/ 01 сентября 2011

Такое поведение гарантировано все время?Приведенный ниже код создает указатель char * с использованием временного unique_ptr.Я думал, что unique_ptr должен быть уничтожен в конце оператора.К моему удивлению, символ * все еще указывает на действительную память.

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;

Ответы [ 3 ]

11 голосов
/ 01 сентября 2011

Это вызывает неопределенное поведение .Неопределенное поведение означает, что может произойти все, в том числе и то, что оно работает.Временный unique_ptr фактически уничтожается, и в результате освобождается 100-элементный массив char.Вы читаете и записываете в область памяти, которая больше не выделена вам.

Просто так получилось, что к моменту работы с ним память, указанная x, не была выделена или прочитана / записана для чего-то другого.Но эта память уже была освобождена временным unique_ptr, поэтому вы не должны связываться с ней.

Только не делайте этого.Если вы хотите сохранить массив, но не unique_ptr, используйте release().

1 голос
/ 01 сентября 2011

Поскольку вы не присвоили переменную типа unique_ptr, вы создали только временную. Память освобождается, как только x инициализируется, прежде чем Fill будет вызван вообще.

Просто сделайте это:

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

Fill(x.get(), 100);

Как уже говорили другие, просто удача, что ваша программа не потерпела крах. Сбои гарантированы редко.

1 голос
/ 01 сентября 2011

Это правда, что x указывает на выделенную память, но эта память была освобождена в конце оператора, и то, на что сейчас x указывает, является недопустимой памятью, и попытка использовать ее вызывает неопределенное поведение.

Программа появляется для работы, потому что память не была выделена для другого процесса.Но нет никакой гарантии, что память не будет выделена другому процессу.

Прочитайте это лучшее объяснение @Eric Lippert здесь:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...