关于 C++ primer 5 版。第 12 章动态内存。
shared_ptr<int> p(new int(42)); // reference count is 1
int *q = p.get(); // ok: but don't use q in any way that might delete its pointer
{ // new block
// undefined: two independent shared_ptrs point to the same memory
shared_ptr<int>(q);
} // block ends, q is destroyed, and the memory to which q points is freed
int foo = *p; // undefined; the memory to which p points was freed
In this case, both p and q point to the same memory. Because they were created independently from each other, each has a reference count of 1. When the block in which q was defined ends, q is destroyed. Destroying q frees the memory to which q points. That makes p into a dangling pointer, meaning that what happens when we attempt to use p is undefined. Moreover, when p is destroyed, the pointer to that memory will be deleted a second time.
如我所见,q
不是 shared_ptr 而是内置指针,因此它没有引用计数。通常他应该说临时 shared_ptr 对象和 p
代替。不是吗?
此外,我认为这段代码不会导致未定义的行为!因为我已经尝试过并且运行良好。因为我猜是这样的表达:
{ // new block // undefined: two independent shared_ptrs point to the same memory shared_ptr<int>(q); // I think this will be removed by the compiler as an optimization. }
因此我认为只有一个 shared_ptr 管理该内存。所以我认为这是安全的。但如果他写道:
{ // new block
// undefined: two independent shared_ptrs point to the same memory
shared_ptr<int> q2(q);
}
那么这就是他的意思。 谢谢!
最佳答案
呈现的代码确实有问题并且没有显示它想要显示的内容,但不是因为某些假定的编译器优化...
行:
shared_ptr<int>(q);
不会创建一个新的临时 shared_ptr
,其中 q 是发送到 shared_ptr 的构造函数的参数! 它创建一个名为 q 的 shared_ptr。
所以这确实是一个错误的代码示例,您提出的修复是正确的。
然而,正如评论中提到的,以下哲学:它运行因此它不是未定义的行为是错误的。
示例中代码的另一个修复可能是使用花括号 {} 将 q 作为临时 shared_ptr
的参数发送:
int main() {
shared_ptr<int> p(new int(42)); // reference count is 1
int *q = p.get(); // ok: but don't use q in any way that might delete its pointer
{ // new block
// undefined: two independent shared_ptrs point to the same memory
shared_ptr<int> {q}; // q is now a parameter to a temporary shared_ptr
} // block ends, q is destroyed, and the memory to which q points is freed
int foo = *p; // undefined; the memory to which p points was freed
}
最后一点 - 为 block 内的 shared_ptr 命名的建议并没有真正放弃编译器优化,只要不使用实际对象,编译器可能会放弃它的创建。因此,如果您想确保编译器优化不会发生,您应该这样做:
int main() {
shared_ptr<int> p(new int(42)); // reference count is 1
int *q = p.get(); // ok: but don't use q in any way that might delete its pointer
{ // new block
// undefined: two independent shared_ptrs point to the same memory
shared_ptr<int> ptr {q}; // q is now a parameter to a local shared_ptr
*ptr = 42; // do something with ptr
} // block ends, q is destroyed, and the memory to which q points is freed
int foo = *p; // undefined; the memory to which p points was freed
return foo; // do something with foo
}
关于C++ 入门 5 版 : using get member to initialize another shared_ptr independent object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58583891/