![](/img/trans.png)
[英]efficient way to search in `QMap<QString, ...>` using `QStringView`
[英]Using QString causes crash after QMap::remove
我有以下代码:
class NamedObjectContainer {
//...
QMap<QString, SomeStruct> mUsed;
//...
};
const StoredObject* NamedObjectContainer::use(const QString& name, const QString& userId)
{
qDebug()<<userId;
mUsed.remove(userId);
qDebug()<<userId;
//...
}
在这里,我试图通过键(userId)从QMap中删除元素。 元素被正确删除。 但令人惊讶的是它在QMap :: remove之后崩溃了打印userId。
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb5b2c6c0 (LWP 24041)]
0xb5fe899c in memcpy () from /lib/i686/nosegneg/libc.so.6
(gdb) where
#0 0xb5fe899c in memcpy () from /lib/i686/nosegneg/libc.so.6
#1 0xb7263246 in QString::append () from /home/osmin/stand_cl_dir/Qt4_x86-linux/lib /libQtCore.so.4
#2 0xb72b6641 in ?? () from /home/osmin/stand_cl_dir/Qt4_x86-linux/lib/libQtCore.so.4
#3 0xb72b218b in QTextStream::operator<< () from /home/osmin/stand_cl_dir/Qt4_x86-linux/lib/libQtCore.so.4
#4 0xb6524740 in QDebug::operator<< () from /usr/lib/libqxmlrpc.so.1
#5 0xb62b5cc0 in tabexchange::NamedObjectContainer::use (this=0x9e2fb08, name=@0xbffe85e4, userId=@0xa12b780) at namedcontainer.cpp:208
什么可能导致问题? 我正在使用Qt 4.4.3
详细说明@ TI的评论......
QString是一种隐式共享类型 。 每个由QString对象组成的新副本都会增加引擎下的引用计数,当计数变为零时,它将被销毁。
这里可能发生的是有一个初始化例程,它创建了一个QString实例,将其作为键传递,并且映射生成了一个副本。 (这不会复制数据,只会增加共享计数。)然后初始化例程销毁了它的实例,因此剩下的唯一共享实例是存储在地图中的共享计数为1的实例。
稍后你可能会使用类似QMap::iterator::key()
来获取地图中字符串键的const引用,并以userId
传入。 这不会创建任何新的QString实例来添加到共享计数,而是指向映射所拥有的那个。 所以当地图放开它时......它被破坏了,现在userId
是一个悬空引用。
(注意:你没有说SomeStruct
。但是如果通过它可以到达一个匹配字符串的实例,当一个地图值的SomeStruct
被销毁时会被破坏,然后传入对这样一个字符串的引用userId
可能会导致类似的问题。)
隐含共享投入混合的一件事是,有时它隐藏了这种性质的错误 - 如果没有隐式共享,这将更加明显。 然而,它使解决方案“便宜”:当您提取密钥以传入时,将其复制到本地变量实例中......并将对该变量的const引用传递给此例程。 这实际上不会复制数据,但它会使userId
安全,因为将有一个共享计数使其保持活动状态。
这有助于实现更普遍的良好协议:将引用类型传递给例程应该意味着您可以保证所调用函数的整个运行时的引用对象的生存期。 如果有疑问,请复制并传递对副本的引用。
(注意:将来,尝试使用简单,自包含,正确的示例格式,包括添加和删除,它可以更容易地找到你自己的吸烟枪。没有它,我们只能做出有根据的猜测问题......它可能是由你的程序中的其他东西造成的!)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.