如何创建一个指向std::vector的shared_ptr?

18

我需要创建一个指向std::vector的shared_ptr,正确的语法是什么?

std::vector<uint8_t> mVector;
shared_ptr<std::vector<uint8_t>> mSharedPtr = &mVector;

上面的代码无法编译。

谢谢。


13
auto p = std::make_shared<std::vector<uint8_t>>(); 可以翻译为:创建一个类型为 std::vector<uint8_t> 的共享指针,使用 std::make_shared 函数生成。 - Ferruccio
3个回答

35
您尝试的是让智能指针管理一个堆栈对象。但这样做是行不通的,因为当堆栈对象超出范围时,它会自我销毁。智能指针无法阻止其执行该操作。
std::shared_ptr<std::vector<uint8_t> > sp;
{
   std::vector<uint8_t> mVector;
   sp=std::shared_ptr<std::vector<uint8_t> >(&mVector);
}
sp->empty();   // dangling reference, as mVector is already destroyed

三种选择:

(1)初始化向量并由shared_ptr管理:
auto mSharedPtr = std::make_shared<std::vector<uint8_t> >(/* vector constructor arguments*/);

(2) 管理向量的副本(通过调用向量复制构造函数):

std::vector<uint8_t> mVector;
auto mSharedPtr = std::make_shared<std::vector<uint8_t> >(mVector);

(3) 移动向量(通过调用向量移动构造函数):
std::vector<uint8_t> mVector;
auto mSharedPtr = std::make_shared<std::vector<uint8_t> >(std::move(mVector));
//don't use mVector anymore.


7
首先,你所做的是非常错误的。如果你想使用shared_ptr来管理指针,请确保它是通过new动态分配而来的,而不是在堆栈上创建的。否则你还不如直接使用指针。
你的代码应该是这样的:
std::vector<uint8_t> mVector;
/* Copy the vector in a shared pointer */
std::shared_ptr<std::vector<uint8_t> > mSharedPtr ( new std::vector<uint8_t>(mVector) );

或者:

std::shared_ptr<std::vector<uint8_t> > mSharedPtr ( new std::vector<uint8_t>() );

为什么代码无法编译,因为你需要使用构造函数而不是=操作符。

正如@remyabel所指出的那样,make_shared更加高效:

std::vector<uint8_t> vector;
/* Copy the vector in a shared pointer */
auto sharedPtr = std::make_shared<std::vector<uint8_t>> (vector);

14
为什么不使用std::make_shared - user3920237
1
是的,make_shared更高效。 - Neil Kirk
1
它还在异常期间提供了更多的内存泄漏保护。 - Bill Lynch
2
请注意,您的 make_shared 版本始终调用向量复制构造函数。您还可以转发向量的构造函数参数。 - davidhigh
1
那个是有意的,因为我正在复制,遵循我对OP意图的理解。变量以m开头,这使得它们很可能是成员变量,所以我不使用std::move - coyotte508

1
你的代码无法编译,因为你正在将裸指针 '&mVector' 分配给智能指针 'mSharedPtr',这是两个不同的对象,不允许进行强制转换。
你可以通过其他方法来解决这个问题。
(1) 从一开始就使用原始指针初始化你的 shared_ptr
std::shared_ptr<std::vector<uint8_t>> sPtr (&mVector);

(2)使用`shared_ptr`的`reset()`方法。
std::shared_ptr<std::vector<uint8_t>> sPtr;
sPtr.reset(&mVector);

将栈对象的原始指针分配给智能指针时,您还应该向智能指针提供一个空删除器,以便在对象仍在堆栈上时智能指针不会删除它。
std::shared_ptr<std::vector<uint8_t>> sPtr (&mVector,[](std::vector<uint8_t>*){});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接