通过将指针放在名为Note
的列表中来存储我的类m_noteList
中的对象:
QList< QSharedPointer<Note> > m_noteList;
我正在通过以下方式创建该类的对象:
QSharedPointer<Note> note(new Note(this));
m_noteList << note;
删除经过(在获得正确的索引idx
以识别对象之后):
delete m_noteList[idx].data();
QtCreator(调试模式)中的错误消息
HEAP[MyApp.exe]:
HEAP: Free Heap block 024FC240 modified at 02500330 after it was freed
并且有责任:
0x777349ab <+0x0000> cmpb $0x0,0x2(%eax)
0x777349af <+0x0000> je 0x777349c6
0x777349b1 <+0x0000> movb $0x1,0x7774d640
0x777349b8 <+0x0000> mov %ecx,0x7774d644
0x777349be <+0x0000> int3
0x777349bf <+0x0000> movb $0x0,0x7774d640 //<-- Here is a stop mark
0x777349c6 <+0x0000> ret
0x777349c7 <+0x0000> nop
...
我也试过这个:
m_noteList.removeAt(idx);
哪个也不起作用。操作系统发出的SIGSEGV
信号停止了进程(Segmentation fault)
所以我真的不知道自己做错了什么以及如何绕过它
我的解决方案很脏:为我的对象设置某种deleted
- 标签,但是我需要在其他所有函数中检查它以忽略该对象...
编辑:
我意识到一件事:如果我删除一个音符(带removeAt()
),它将被删除(我通过观看控制台打印输出看到它),但它的gui不会消失。然后,如果我再次单击该对象的特定按钮以删除该注释,则应用程序崩溃(因为它不再存在,只有gui)。但是如果我之前写这个deleteLater
,在删除它之后,gui也会消失,一切似乎都很好。
有人可以解释,为什么?
m_noteList.at(idx)->deleteLater();
m_noteList.removeAt(idx);
答案 0 :(得分:2)
您正在混淆三个内存管理策略:
QObject
父子内存管理:当删除父QObject
时,它会自动删除所有子QObjects
。解释here。删除对象是自动完成的,因此不需要显式删除。
QSharedPointer
内存管理:删除引用对象的最后一个QSharedPointer
时,删除该对象。解释here。该对象会自动删除,因此无需显式删除。
&#34;手动&#34;内存管理:new
一个对象,delete
一个对象在合适的时间。在C ++标准中解释。必须手动删除该对象。
您应该只选择上述之一,以确保不会双重删除对象。我建议在#1和#2之间进行选择,具体取决于您打算如何使用这些对象。如果您计划在&#34; parent&#34;之间共享对象,请使用#2,否则使用#1。
答案 1 :(得分:0)
给出QList<QSharedPointer<Note>> m_noteList
:
Note
对象的删除由m_noteList.removeAt(idx)
完成,假设没有其他现存的指针副本。你只需要破坏给定音符的最后一个共享指针即可。在共享指针的数据上调用delete
始终是错误。
我无法使用removeAt
重现您的问题 - 只有当您首先delete
注意时才会重现您的问题。