删除使用 "new" 创建的对象
Deleting an object created with "new"
我的类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
信号停止进程(分段错误)
所以我真的不知道我做错了什么以及如何解决它
我的解决方案很脏:为我的对象设置某种 deleted
-tag,但我需要在所有其他函数中检查它以忽略该对象......
编辑:
我意识到一件事:如果我删除一个音符(带removeAt()
),它就会被删除(我通过观看控制台打印输出看到它),但它的 gui 不会消失。然后,如果我再次单击该对象的特定按钮以删除注释,应用程序将崩溃(因为它不再真正存在,而只是 gui)。但是如果我之前写这个deleteLater
,删除它之后,gui 也会消失,一切似乎都很好。有人可以解释一下,为什么?
m_noteList.at(idx)->deleteLater();
m_noteList.removeAt(idx);
您混合了三种内存管理策略:
-
QObject
父子内存管理:删除父QObject
时,会自动删除所有子QObjects
。在这里解释。删除对象是自动完成的,因此不需要显式删除。 -
QSharedPointer
内存管理:删除引用对象的最后一个QSharedPointer
时,将删除该对象。在这里解释。对象会自动删除,因此不需要显式删除。 -
"手动"内存管理:
new
对象并在正确的时间delete
对象。在C++标准中进行了解释。必须手动删除该对象。
您应该只选择上述选项之一,以确保不会重复删除对象。我建议在#1和#2之间进行选择,具体取决于您计划如何使用对象。如果您计划在"父项"之间共享对象,请使用 #2,否则使用 #1。
给定一个QList<QSharedPointer<Note>> m_noteList
:
Note
对象的删除是通过m_noteList.removeAt(idx)
完成的,假设没有其他现存的指针副本。您只需销毁指向给定笔记的最后一个共享指针,仅此而已。对共享指针的数据调用delete
始终是错误的。
我无法用removeAt
重现您的问题 - 只有当您先delete
注释时才会发生这种情况,这是您不应该做的。
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 具有包含其他对象的类的对象创建顺序
- 为什么我们再次从结构对象创建结构变量?
- 将对象创建为全局/静态对象会崩溃,而本地对象不会崩溃
- 如何创建一个对象创建函数,该函数将由与其关联的名称调用?
- 如何为自定义模板对象创建专门的函数模板
- 对象创建错误的C++矢量
- 如何为Python Swigged C++对象创建和分配回调函数
- 在 C++ 中为 C 样式对象创建一个透明包装类
- 此类模板的对象创建如何工作?
- C++ 中的对象创建类型有什么区别?
- 未知大小的数组作为类成员,用于在运行时(对象创建时间)创建数组的对象
- 如何仅通过父类对象限制对象创建
- 在正确性或良好的代码结构方面,这种动态对象创建看起来如何
- 无法将类对象创建为另一个类的成员
- 如何从现有基类对象创建派生类对象
- 在 DTor 之前删除的静态对象创建的线程?
- C++:定义多个构造函数时的对象创建/销毁序列
- 从对象创建矢量包装器,该对象只允许使用索引访问向量
- 是否可以为CPP中的对象创建一组指针