gpt4 book ai didi

C++ weak_ptr.lock() 段错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:29:09 25 4
gpt4 key购买 nike

所以我有这个函数来添加监听器,它转换一个类的共享指针,以便我稍后在收到通知时可以调用它。

void registerListener(std::shared_ptr<T> listener)
{
if (!listener) {
qCWarning(OBSERVER_LOGGER) << "Attempted to register a null observer.";
return;
}
// TODO make a foreach function that removes dead listeners to get rid of this code dupe
for (auto iter=listeners.begin(); iter != listeners.end(); ) {
if (auto shared = iter->lock()) {
if (listener == shared) {
return;
}
iter++;
} else {
iter = listeners.erase(iter);
}
}
auto weak = std::weak_ptr<T>(listener);
listeners.push_back(weak);
}

void notify(std::function<void(std::shared_ptr<T>)> onNotify)
{
// TODO make a foreach function that removes dead listeners to get rid of this code dupe
for (auto iter=listeners.begin(); iter != listeners.end(); ) {
if (auto shared = iter->lock()) {
onNotify(shared);
iter++;
} else {
iter = listeners.erase(iter);
}
}
}

private:
std::vector<std::weak_ptr<T>> listeners;

并且出于某种原因,“iter->lock()”段错误。我会说这是一个 Qt 应用程序,但我故意没有创建任何线程(据我所知)所以我非常困惑我做错了什么让这些 weak_ptrs 中断。所以如果我在 gdb 中运行它,它工作得很好。但是,如果我设置“关闭禁用随机化”,则会出现错误。所以我觉得这是一个奇怪的问题,其中有未初始化的变量。如果有帮助,这是我在 gdb 中崩溃时的堆栈。

#0  0x00007f856bd8beec in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_get_use_count() const ()
#1 0x00007f856bd844a8 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_lock_nothrow() ()
#2 0x00007f856bd9cd7d in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__weak_count<(__gnu_cxx::_Lock_policy)2> const&, std::nothrow_t) ()
#3 0x00007f856bda9948 in std::__shared_ptr<IEntityListener<Assignment>, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__weak_ptr<IEntityListener<Assignment>, (__gnu_cxx::_Lock_policy)2> const&, std::nothrow_t) ()
#4 0x00007f856bda8a62 in std::shared_ptr<IEntityListener<Assignment> >::shared_ptr(std::weak_ptr<IEntityListener<Assignment> > const&, std::nothrow_t) ()
#5 0x00007f856bda701a in std::weak_ptr<IEntityListener<Assignment> >::lock() const ()
#6 0x00007f856bda5624 in Observer<IEntityListener<Assignment> >::notify(std::function<void (std::shared_ptr<IEntityListener<Assignment> >)>) ()
#7 0x00007f856bda3a1a in EntityObserver<Assignment>::notifyCreated(std::shared_ptr<Assignment>) ()

编辑:Michael Burr 发布了在添加新听众的同时听众注册的可能性,这完全有可能发生。这将导致迭代器无效,并且当我去调用 weak_ptr.lock() 上不是 weak_ptr 的内存部分时,BOOM。我认为这里有一个寓意,我必须找到它。

最佳答案

notify() 被调用时,通过 onNotify() 函数对象调用的函数是否有可能导致 registerListener()被间接调用(或其他一些可以在 listeners 集合中添加或删除条目的代码)?

如果是这样,则可以使 notify() for 循环中使用的 iter 失效。您可能希望将 notify() 更改为如下所示,它将所有 shared_ptr 对象排队以进行通知,这样 监听器是否无关紧要 集合在任何 onNotify() 回调期间被修改:

#include <queue>

void notify(std::function<void(std::shared_ptr<T>)> onNotify)
{
std::queue<std::shared_ptr<T>> notify_targets;

for (auto iter=listeners.begin(); iter != listeners.end(); ) {
if (auto shared = iter->lock()) {
notify_targets.push(shared);
iter++;
} else {
iter = listeners.erase(iter);
}
}

while (!notify_targets.empty()) {
onNotify(notify_targets.front());
notify_targets.pop();
}

}

关于C++ weak_ptr.lock() 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28358532/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com