Построение умного указателя из стека, выделенного необработанным указателем - PullRequest
0 голосов
/ 12 февраля 2020

Может кто-нибудь просветить меня в том, что здесь происходит?

int* stackint = new int(5);

{
    std::unique_ptr<int> myInt(stackint);    
    *myInt = 8;

}

std::cout << *stackint; // 0

Что именно здесь происходит? Я понимаю умные указатели, когда вы создаете их с помощью new или make_unique, что происходит, когда вы передаете указатели стека их конструктору?

Ответы [ 2 ]

5 голосов
/ 12 февраля 2020

Вот аннотация:

int* stackint = new int(5);   // an int is allocated on the heap, and set to 5
{
   std::unique_ptr<int> myInt(stackint);  // myInt takes ownership of the allocation
   *myInt = 8;  // The value 5 is overwritten by 8
}  // myInt goes out of scope, its destructor deletes the heap allocation        

std::cout << *stackint; // undefined behavior:  attempt to read from already-freed memory
2 голосов
/ 12 февраля 2020

Код имеет неопределенное поведение.

std::unique_ptr<int> myInt(stackint); создает unique_ptr владеющего объектом , который stackint указывает на . Какой тип хранилища имеет сам указатель, не имеет значения, только его значение передается в конструктор, а значение указывает на объект int, созданный путем вызова new, что означает, что это int объект имеет динамический c срок хранения .

myInt деструктор затем вызывается в конце блока (}) и delete с int объект, которым он управлял и на который stackint все еще указывал, что означает, что значение stackint теперь является недопустимым значением указателя .

Затем вы разыменовываете это неверное значение указателя с помощью *stackint, что вызывает неопределенное поведение.

...