I'm storing a class (let's call it A
) in an std::vector
using C++ smart pointers (so the vector sigature is 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;
}
For some reason, this throws a std::bad_weak_ptr
, and upon inspection I notice that a
, for whatever reason, has an _M_weak_this
equal to 0x0
, or NULL
. Since I've already created a valid std::shared_ptr
referencing the object, it shouldn't be empty.
Furthermore, I know no memory corruption is occurring because A
(with variables) is completely intact at its address.
What am I doing wrong?
A
class inherits enable_shared_from_this with public ? – Multiversityshared_ptr<A>
, one beinga
and another one in the vector and then ask for a third one witha->getSharedRef()
? – Guildershared_ptr<A>
in thevector
, and then ask for (and return) anothershared_ptr<A>
referencing the same object. Perhaps I'm misusing smart pointers - they're a little touchy, and I'm a little unsure if I'm going about this in the "correct" way. – Standpush_back(a)
it effectively creates a copy of it. Afterwards, you havea
and theshared_ptr<A>
in the vector that points to the class instance. You could create A in-placev.emplace_back(std::make_shared<A>());
(if your shared_ptr vector isv
) so that onlyv
has a pointer to it. – Guilder