在AUI Framework的槽函数中获取接收者状态为何触发段错误?
问题:使用AUI Framework信号槽时触发段错误
我正在使用具有Qt相似信号槽机制的AUI Framework,想要访问接收者对象的状态,于是在C++ lambda中捕获接收者对象,代码如下:
auto model = _new<ATreeModel<AString>>(...); _new<ATreeView>(model).connect(&ATreeView::itemSelected, model, [this, &model](ATreeModelIndex index){ auto selected = model->itemAt(index); // ... });
运行时出现错误:[UI thread][SignalHandler][ERR]: Caught signal: Segmentation fault(11)
原因分析
- lambda引用捕获悬空:你用引用捕获
&model,但model是栈上的局部指针变量。当前代码块执行结束后,栈上的model会被销毁,lambda内的引用就成了悬空引用,信号触发时访问该引用直接导致段错误。 - ATreeView对象未被持有:
_new<ATreeView>(model)创建的对象没有被任何变量保存,若AUI的对象生命周期管理依赖持有引用,该视图对象可能被提前销毁,信号槽连接失效后触发非法内存访问。
解决方法
- 修改lambda捕获方式:将引用捕获改为值捕获,因为
model是指针,值捕获仅复制指针本身,不会额外开销,且避免悬空引用:[this, model](ATreeModelIndex index){ auto selected = model->itemAt(index); // ... } - 持有ATreeView对象:用变量保存创建的视图对象,防止其被提前销毁:
auto model = _new<ATreeModel<AString>>(...); auto treeView = _new<ATreeView>(model); treeView->connect(&ATreeView::itemSelected, model, [this, model](ATreeModelIndex index){ auto selected = model->itemAt(index); // ... });
内容的提问来源于stack exchange,提问作者Alex2772
相关产品推荐
相关产品推荐

