Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对象在std::unique_ptr超出范围后仍可访问。不同的运行时行为_C++_C++11_Unique Ptr_Dangling Pointer - Fatal编程技术网

C++ 对象在std::unique_ptr超出范围后仍可访问。不同的运行时行为

C++ 对象在std::unique_ptr超出范围后仍可访问。不同的运行时行为,c++,c++11,unique-ptr,dangling-pointer,C++,C++11,Unique Ptr,Dangling Pointer,下面的代码传递给函数modify_entry一个指向entry类型的对象的指针,函数体内部的unique_ptr采用原始指针。但是,指针指向的对象似乎在函数返回后仍然存在 当我编译这段代码时 #include <iostream> #include <memory> struct Entry { Entry(std::string name) : name_(name) { std::cout << "Constructor fo

下面的代码传递给函数
modify_entry
一个指向
entry
类型的对象的指针,函数体内部的
unique_ptr
采用原始指针。但是,指针指向的对象似乎在函数返回后仍然存在

当我编译这段代码时

#include <iostream>
#include <memory>

struct Entry {
    
    Entry(std::string name) : name_(name) { std::cout << "Constructor for " + name_ + '\n'; }
    ~Entry() { std::cout << "Destructor for " + name_ + '\n'; }
    std::string name_;
    
};

void modify_entry(Entry* e_ptr){
    
    std::cout << "Inside modify_entry()\n";
    std::unique_ptr<Entry>{e_ptr}->name_ += " Doe";

}

int main(int argc, const char * argv[])
{
        
    Entry* entry_ptr = new Entry("John");
    modify_entry(entry_ptr);
    std::cout << "Back from modify_entry()\n";
    std::cout << entry_ptr->name_ << '\n';      // <---- line 25
            
    return 0;
    
}
#包括
#包括
结构条目{
条目(std::string name):名称(name){std::cout
问:为什么在运行由clang生成的可执行文件时没有运行时错误

因为未定义的行为是未定义的。程序试图在其生命周期结束后访问对象。C++定义了此类程序的行为。< /P>

make_unique
unique_ptr
等的移动语义非常好,而这类东西正是您应该使用它们的另一个原因

问:为什么在运行由clang生成的可执行文件时没有运行时错误

因为未定义的行为是未定义的。程序试图在其生命周期结束后访问对象。C++定义了此类程序的行为。< /P>


make_unique
unique\u ptr
等的移动语义非常好,而这正是您应该使用它们的另一个原因。

因为您所做的是,当在
main
函数中使用指向已破坏对象的指针时


对象已被销毁(删除),但仍有指向其所在位置的指针,取消引用此指针将导致未定义的行为。

因为您所做的是,在
main
函数中使用指向已销毁对象的指针

对象已被销毁(删除),但仍有指向其所在位置的指针,取消引用此指针将导致未定义的行为

但是,指针指向的对象似乎在函数返回后仍然存在

这里的关键是“似乎”。实际上,
条目的生命周期在这一行的末尾结束:

 std::unique_ptr<Entry>{e_ptr}->name_ += " Doe";
std::unique_ptr{e_ptr}->name_u+=“Doe”;
unique\u ptr
已经取得了内存的所有权,但是临时的
unique\u ptr
的生命周期在该语句结束时结束,因此它还删除了它所拥有的
条目。访问以前由对象使用的内存是未定义的行为。它在某些平台上工作,而不是在其他平台上工作只是n未定义行为的性质

但是,指针指向的对象似乎在函数返回后仍然存在

这里的关键是“似乎”。实际上,
条目的生命周期在这一行的末尾结束:

 std::unique_ptr<Entry>{e_ptr}->name_ += " Doe";
std::unique_ptr{e_ptr}->name_u+=“Doe”;

unique\u ptr
已经取得了内存的所有权,但是临时的
unique\u ptr
的生命周期在该语句结束时结束,因此它还删除了它所拥有的
条目。访问以前由对象使用的内存是未定义的行为。它在某些平台上工作,而不是在其他平台上工作只是n未定义行为的本质。

同意这一点,你不能依赖于未初始化内存的差异。同意这一点,你不能依赖于未初始化内存的差异。请阅读,尤其是已接受的答案。@Angew谢谢。当然,我在发布我的问题之前搜索过类似的问题,但标签有时可能会误导。我明白了你的观点,但不幸的是,我无法阅读被接受的答案;它以一个寓言开始……阅读,尤其是被接受的答案。@Angew谢谢。当然,在我发布我的观点之前,我搜索了类似的问题,但标签有时可能会误导。我明白你的观点,但不幸的是,我无法阅读被接受的答案;它以w开头用一个寓言。。。