有人可以解释为什么在退出内部作用域时以下内容会在 main() 中崩溃吗?我正在使用 Visual Studio 2013。虽然 GCC 4.8.1 一切正常,但我怀疑代码中有问题。我就是不明白。
#include <iostream>
#include <memory>
class Person; class PersonProxy;
class PersonInterface {
public:
virtual ~PersonInterface() = default;
virtual PersonProxy* getProxy() const = 0;
virtual void createProxy (Person*) = 0;
};
class Person : public PersonInterface {
private:
std::string name;
std::shared_ptr<PersonProxy> proxy;
public:
Person() = default;
explicit Person (const std::string& n) : name(n) {}
public:
virtual PersonProxy* getProxy() const override {return proxy.get();}
inline void createProxy (Person* p);
};
class PersonProxy : public PersonInterface {
private:
std::shared_ptr<Person> actual;
public:
explicit PersonProxy (Person* p) : actual (std::shared_ptr<Person>(p)) {}
explicit PersonProxy (std::shared_ptr<Person> p) : actual (p) {}
void rebind (std::shared_ptr<Person> p) {actual = p;}
virtual PersonProxy* getProxy() const override {return actual->getProxy();}
virtual void createProxy (Person* p) override {actual->createProxy(p);}
};
class Girl : public Person {
public:
Girl (const std::string& name) : Person (name) {createProxy (this);}
};
inline void Person::createProxy (Person* p) {
proxy = std::shared_ptr<PersonProxy>(new PersonProxy(p));
}
int main() {
{
Girl* a = new Girl("a");
// std::shared_ptr<Girl> a = std::make_shared<Girl>("a"); // Using this crashes with Visual Studio 2013 on the line 'a->getProxy()->rebind(b);'
std::shared_ptr<Girl> b = std::make_shared<Girl>("b");
a->getProxy()->rebind(b);
std::cout << "rebind succeeded." << std::endl;
}
std::cout << "Exited scope." << std::endl; // Exiting scope crashes with VS 2013.
}
我在 VS2013 中得到的错误信息是:
断言失败
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
最佳答案
您有两个 shared_ptr
试图拥有同一个指针(并且它们彼此不了解)。这导致他们都试图释放同一个地址。
a
正在尝试取得 this
的全部所有权。但是随后您将 this
传递给 CreateProxy()
,它会创建一个新 shared_ptr
来尝试获取 这个
。新的 shared_ptr
不知道 a
,所以两者都没有共享它们的引用计数。 shared_ptr
需要共享它们的引用计数,而不仅仅是指针本身。
如果你想在两个 shared_ptr
之间共享一个指针,它们需要彼此了解(以便它们可以更新它们的引用计数)。当Girl
调用createProxy()
时,需要传递一个shared_ptr
给this
。
也许现在是使用 std::enable_shared_from_this()
的好时机.
关于c++ - shared_ptr 的神秘崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25949816/