【问题标题】:Naked pointer to unique_ptr指向 unique_ptr 的裸指针
【发布时间】:2014-05-25 17:16:45
【问题描述】:

我有一个带有向量的结构,我需要存储一个指向其中一项的指针。使用裸指针,我会这样做:

#include <iostream>
#include <vector>
#include <memory>
#include <unistd.h>

struct A {
    A () {
        v = {1, 2, 3, 4};
        uv = &v.front();
    }

    std::vector<int> v;
    int* uv;
};

int main()
{
    A a;
    std::cout << *a.uv << std::endl;
    return 0;
}

现在,我可以用make_shared 摆脱裸指针:

struct A {
    A () {
        v = {1, 2, 3, 4};
        uv = std::make_shared<int>(v.front());
    }

    std::vector<int>     v;
    std::shared_ptr<int> uv;
};

由于 C++11 还没有实现 make_unique,我如何使用 unique_ptr 做同样的事情?我尝试通过将uv 设为unique_ptr 并调用uv.reset(&amp;v.front()); 来分配前端元素,但出现以下错误:

malloc: *** error for object 0x7f856bc0bcf0: pointer being freed was not allocated

有什么帮助吗?谢谢

【问题讨论】:

  • 那个指针不拥有任何东西。不要为此使用智能指针。使用原始指针或迭代器。
  • 实际上,您不应该从引用中获取指针并将其永久存储。 &amp;v.front() 仅在 v 不变时有效。实际上uv 并没有指向需要释放的内存。
  • 我不相信您对 unique_ptr 的预期使用是规范的。 FWIW,您可以使用构造函数初始化 unique_ptr: unique_ptr ptr(new int);或者您可以使用另一个 unique_ptr 进行初始化,但您必须移动数据: unique_ptr other(move(ptr));这是因为 unique_ptr 是可移动可分配和可移动构造的,但不能复制可分配也不可复制构造。目的是保留所有权,并清楚说明什么负责销毁该对象。正如您正确指出的那样,make_unique 将出现在 C++14 中,直到那时我们都坚持使用旧语法。
  • 这似乎是一个 XY 问题。 OP 正在存储一个指向它不拥有的内部地址的迭代器/指针(如果向量的状态发生变化,则可能无效)。很有可能这确实是一个设计问题 - 您要解决的实际问题是什么?

标签: c++ pointers c++11 unique-ptr


【解决方案1】:

std::unique_ptr 背后的哲学是所有权,即它是一个拥有内存区域的对象,将后者的生命周期与自己的生命周期联系在一起。

std::vector 遵循相同的路径:它声明对其包含的元素的所有权。因此,当它的析构函数运行时,它会触发其元素的析构函数(如果它们是用户定义的类型)。

在您的情况下,v 拥有v.front(),但您也将此责任交给了uv。现在,他们俩将尝试销毁同一个对象。

这里最好使用原始指针,或者(更好)迭代器,因为它仅用作观察者。

【讨论】:

  • 如何在这里使用迭代器?只是“int uv = v.front()”?
  • auto uv = v.begin()?
  • 但我不能将“auto”作为结构成员,因为它不是实际类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-04
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多