C++ 在QMap::remove之后使用QString会导致崩溃
我有以下代码:C++ 在QMap::remove之后使用QString会导致崩溃,c++,qt,qmap,C++,Qt,Qmap,我有以下代码: class NamedObjectContainer { //... QMap<QString, SomeStruct> mUsed; //... }; const StoredObject* NamedObjectContainer::use(const QString& name, const QString& userId) { qDebug()<<userId; mUsed.remove(u
class NamedObjectContainer {
//...
QMap<QString, SomeStruct> mUsed;
//...
};
const StoredObject* NamedObjectContainer::use(const QString& name, const QString& userId)
{
qDebug()<<userId;
mUsed.remove(userId);
qDebug()<<userId;
//...
}
类名称对象容器{
//...
QMap沉思着;
//...
};
const StoredObject*namedbjectcontainer::use(const-QString&name,const-QString&userId)
{
qDebug()详细说明@TI的评论
QString是一个。QString对象的每个新副本都会增加引擎盖下的引用计数,当计数变为零时,它将被销毁
这里可能发生的情况是,有一个初始化例程生成了一个QString实例,将其作为键传入,映射生成了一个副本(这并没有复制数据,只是增加了共享计数)然后初始化例程销毁了它的实例,因此剩下的唯一共享实例是存储在映射中的共享计数为1的实例
稍后,您可能会使用类似的方法获取映射中字符串键的常量引用,作为userId
传入。这不会创建任何要添加到共享计数的QString的新实例,而是指向映射所拥有的一个实例。因此,当映射释放它时,它将被销毁,而现在userId
是一个悬而未决的问题参考资料
(注意:您没有说SomeStruct
中有什么内容。但是如果通过它可以到达键的匹配字符串的实例,当映射值的SomeStruct
被销毁时,该实例将被销毁,那么传入对userId
这样的字符串的引用可能会导致类似的问题。)
隐式共享带来的一个问题是,有时它会隐藏这种性质的错误——如果没有隐式共享,这种错误会变得更加明显。但它使解决方案变得“便宜”:提取要传入的密钥时,将其复制到局部变量实例中…并将该变量的常量引用传递到此例程。这实际上不会复制数据,但会使userId
安全,因为将有一个共享计数使其保持活动状态
这有助于实现更普遍的好协议:将引用类型传递给例程意味着您可以在调用的函数的整个运行时保证引用对象的生存期。如果有疑问,请创建一个副本,并传递对副本的引用
(注意:将来,尝试使用包含“添加”和“删除”的格式,这样可以更轻松地自己查找冒烟枪。如果没有它,我们只能对问题进行有根据的猜测……这完全可能是由程序中的其他内容引起的!)传递给函数的用户ID来自何处?如果它直接来自mUsed,则可能正在从映射中删除它,然后您正试图打印对已删除内容的引用?如果传递mUsed[something]:try const QString tmp=mUsed[something];…use(name,tmp)。。。
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