【发布时间】:2018-05-26 02:41:00
【问题描述】:
我使用 C++ 智能指针将一个类(我们称之为 A)存储在 std::vector 中(因此向量签名是 std::vector<std::shared_ptr<A>>)。
#include <iostream>
#include <memory>
#include <vector>
class A : std::enable_shared_from_this<A> {
public:
void doWork();
std::shared_ptr<A> getSharedRef();
};
void A::doWork() { std::cout << "Working..." << std::endl; }
std::shared_ptr<A> A::getSharedRef() { return shared_from_this(); }
class AManager {
static std::vector<std::shared_ptr<A>> aList;
public:
static void init(); // safety because statics
static void doLotsOfWork();
static std::shared_ptr<A> createA();
};
std::vector<std::shared_ptr<A>> AManager::aList;
void AManager::init() { aList = std::vector<std::shared_ptr<A>>{}; }
void AManager::doLotsOfWork() {
for (auto a : aList) {
a->doWork();
}
}
std::shared_ptr<A> AManager::createA() {
std::shared_ptr<A> a = std::make_shared<A>();
aList.push_back(a);
return a->getSharedRef(); // <----- EXCEPTION
}
int main() {
AManager::init();
AManager::createA();
return 0;
}
由于某种原因,这会引发std::bad_weak_ptr,并且经过检查,我注意到a,无论出于何种原因,都有一个等于0x0 或NULL 的_M_weak_this。因为我已经创建了一个有效的std::shared_ptr 引用该对象,所以它不应该为空。
此外,我知道没有发生内存损坏,因为A(带有变量)在其地址处完全完好无损。
我做错了什么?
【问题讨论】:
-
你的描述很不错。提供准确重现错误的代码会更好。了解如何创建minimal reproducible example
-
在这种特殊情况下,MCVE 的最大问题是代码依赖于许多移动部件,我不确定是哪些部件产生了错误。我确实有相关代码的 github 链接,但否则需要几个小时才能启动一个工作示例。
-
为什么需要 getsharedref() ? (而不仅仅是直接使用 shared_from_this() ?)是因为 A 私有继承吗?如果是,那可能是问题所在......
-
@CalmBit,我知道你来自哪里;创建 MCVE 并不总是那么容易,但它通常是必要的步骤。除了使您的问题非常容易回答之外,您可能会发现您自己解决了这个问题(如果没有,您总是会学到一些东西)。您可能还会发现您问错了问题(您认为问题是由于 X,但实际上是由于 Y)。最后,这听起来可能很荒谬,但创建 MCVE 表明您尊重回答者的时间,不要指望他们会通灵。
-
@AndyG - 我绝对不指望这里有人会通灵!我确实尊重你的时间,尽管我因为在这个单一的错误上浪费了大约 6 个小时而有点受不了——如果我有点粗鲁,请道歉。找到断点后会尽快添加 MCVE。
标签: c++ c++11 vector stl shared-ptr