C++ Primer 第 5 版中发现的错误 shared_ptr<int>

问题描述

嗨,我正在阅读 C++ 入门第 5 版,我想我在 shared_ptr 部分发现了一个错误。首先,我正在编写代码和他们给出的解释。然后我会写出我认为的错误以及我认为实际发生的事情。代码如下:

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 started
    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

他们给出的解释如下:

在这种情况下,p 和 q 都指向同一个内存。因为它们是相互独立创建的,所以每个的引用计数都是 1。当定义 q 的块结束时,q 被销毁。销毁 q 会释放 q 指向的内存。这使得 p 成为一个悬空指针,这意味着当我们尝试使用 p 时会发生什么是未定义的。此外,当 p 被销毁时,指向该内存的指针将再次被删除

现在我认为错误是语句“当定义 q 的块结束时,q 被销毁。销毁 q 释放 q 指向的内存。”以及他们给出的推理为什么 p 是悬空指针的背后是错误的。下面是我为什么 p 是悬空指针以及为什么第一个引用的语句是错误的推理。

  1. 当定义 q 的块结束时,q 被销毁。但是 q 指向的内存没有被释放,因为 q一个内置指针而不是一个 shared_ptr。除非我们明确写入 delete q,否则不会释放相应的内存。
  2. 现在,在新块中,我们使用 q 创建了一个临时的 shared_ptr。但是这个临时文件p 无关。所以当这个内部块结束时,临时块被销毁,因此内存被释放。但请注意 p 仍指向已释放的相同内存。所以 p 现在是一个悬空指针,在语句 p 中使用 int foo=*p 是未定义的。

我认为这是对为什么 p 是悬空指针的正确解释,也是应该存在的更正。有人可以确认这是正确的还是我做错了什么?

解决方法

正如您正确指出的那样,文本描述和代码中的注释都不适合代码。它们更符合这样的代码:

shared_ptr<int> p(new int(42));// reference count is 1
{//new block started
    shared_ptr<int> q(p.get());
}// 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

如果让我猜的话,我会说这就是示例最初的样子,然后有人决定引入原始指针,却没有意识到它也需要更改注释和文本。