【发布时间】:2021-06-15 03:05:41
【问题描述】:
我设计了一个App,其中包含一堆layers 和一个活动的obj。
当Layer 附加到App 时,Layer 告诉App 什么是活动的object。但是我的设计在解除分配时会导致一个信号陷阱。
它会导致 sigtrap,因为 App 中 shared_ptr<Obj> m_obj 的破坏首先发生,这会将 use_count 减少到 1。然后调用 onDetech 函数,将活动的 shared_ptr<Obj> m_obj 设置为 nullptr 并减少 use_count为0!但是layer 仍然拥有shared_ptr<Obj>。
下面的代码是重现的最小示例。我注意到我的代码有一个引用循环,但我不知道如何解决这个问题,除非在 App 类中使用 obj 的原始指针。
我在App 中使用shared_ptr 代替obj,因为App 拥有obj 的共享所有权对我来说是有意义的。在这种情况下我不应该使用shared_ptr吗?
class App;
class Obj {
public:
~Obj() { std::cout << "obj destruct" << std::endl; }
};
class Layer {
public:
Layer() { m_obj = std::make_shared<Obj>(); }
~Layer() { std::cout << m_obj.use_count() << std::endl; }
void onAttach(App *app);
void onDetach();
std::shared_ptr<Obj> m_obj;
private:
App *m_app;
};
class LayerStack {
public:
void pushLayer(App *app, std::shared_ptr<Layer> layer) {
m_layers.push_back(layer);
layer->onAttach(app);
}
~LayerStack() {
for (auto &layer : m_layers) {
layer->onDetach();
}
}
private:
std::vector<std::shared_ptr<Layer>> m_layers;
};
class App {
public:
App() {
m_defaultLayer = std::make_shared<Layer>();
m_stack.pushLayer(this, m_defaultLayer);
}
~App() {}
LayerStack m_stack;
std::shared_ptr<Layer> m_defaultLayer;
std::shared_ptr<Obj> m_activeObj;
};
void Layer::onAttach(App *app) {
m_app = app;
app->m_activeObj = m_obj;
std::cout << m_obj.use_count() << std::endl;
}
void Layer::onDetach() {
m_app->m_activeObj = nullptr;
std::cout << m_obj.use_count() << std::endl;
}
int main() {
A a;
}
输出:
2
obj destruct
-923414512
-923414512
【问题讨论】:
-
感谢您的建议。我已经更新了我的代码示例。但是我描述的问题仍然存在。
use_count减少为负数。 -
它并没有减少到负数,你只是在阅读垃圾。 Address Sanitizer 免费后可以找到你用过的地方:godbolt.org/z/s1YxbsWdc
标签: c++ shared-ptr weak-ptr