Mic*_* Ma 5 shared-ptr undefined-behavior delete-operator c++11
我写了一些这样的代码:
\n\nshared_ptr<int> r = make_shared<int>();\nint *ar = r.get();\n\ndelete ar; // report double free or corruption\n// still some code\nRun Code Online (Sandbox Code Playgroud)\n\n当代码运行到 时delete ar;,程序崩溃,并报告\xe2\x80\x8b“双重释放或损坏”,我很困惑为什么双重释放?“r”仍然在范围内,并且没有从堆栈中弹出。删除操作符有什么神奇的作用吗?它是否知道原始指针当前由智能指针处理?然后“r”中的计数器自动减为零?\n我知道不推荐操作\xef\xbc\x8c,但我想知道为什么?
Dan*_*iel -2
\n看这里。我引用:
\n\n\nstd::shared_ptr 是一个智能指针,它通过指针保留对象的共享所有权。多个shared_ptr对象可能拥有同一个对象。当发生以下任一情况时,该对象将被销毁并释放其内存:
\n\n\n
\n\n- 拥有该对象的最后剩余的shared_ptr被销毁;
\n- 拥有该对象的最后一个剩余的shared_ptr通过operator=或reset()分配另一个指针。
\n使用delete表达式或在构造期间提供给shared_ptr的自定义删除器来销毁该对象。
\n
所以指针被删除了shared_ptr。您不应该自己删除存储的指针\n
更新:
\n\n我没有意识到还有更多的语句,并且指针没有超出范围,对不起。
\n\n我读了更多内容,标准并没有过多说明 的行为get(),但这里有一个注释,我引用:
\n\n\nShared_ptr 可以共享一个对象的所有权,同时存储指向另一个对象的指针。get() 返回存储的指针,而不是托管指针。
\n
所以看起来允许返回的指针get()不一定是由shared_ptr(大概使用new)分配的同一指针。所以delete该指针是未定义的行为。我将进一步研究细节。
更新2:
\n\n标准在 \xc2\xa7 20.7.2.2.6 (大约make_shared)处说:
\n\n\n6 备注:鼓励但不要求实现执行不超过一次的内存分配。[注意:这提供了与侵入式智能指针相当的效率。\xe2\x80\x94 尾注]
\n\n7 [ 注意:这些函数通常会分配比 sizeof(T) 更多的内存,以允许内部簿记结构,例如引用计数。\xe2\x80\x94 尾注]
\n
因此,特定的实现make_shared 可以分配单个内存块(或更多)并使用该内存的一部分来初始化存储的指针(但可能不是分配的所有内存)。get()必须返回一个指向存储对象的指针,但正如前面所说,标准没有要求返回的指针get()必须是 分配的指针new。因此delete该指针是未定义的行为,您收到了一个信号,但任何事情都可能发生。
| 归档时间: |
|
| 查看次数: |
3077 次 |
| 最近记录: |