C++ 为什么可以';我不能删除用new创建的食人魔覆盖系统吗?

C++ 为什么可以';我不能删除用new创建的食人魔覆盖系统吗?,c++,pointers,access-violation,ogre,C++,Pointers,Access Violation,Ogre,我正在为我的应用程序使用Ogre框架。当应用程序关闭时,我关闭了Ogre,删除了Ogre::Root对象。之后,我需要删除一些指针,因为我使用的每个Ogre类都有自己的类作为接口。我只是删除指向我的类的指针。存在于Ogre元素的指针不会被删除,因为Ogre关闭会处理它(或者根据文档至少应该如此) 问题出在OverlySystem类中。这是头文件: class OverlaySystem { public: OverlaySystem(); Ogre::OverlaySystem*

我正在为我的应用程序使用Ogre框架。当应用程序关闭时,我关闭了Ogre,删除了Ogre::Root对象。之后,我需要删除一些指针,因为我使用的每个Ogre类都有自己的类作为接口。我只是删除指向我的类的指针。存在于Ogre元素的指针不会被删除,因为Ogre关闭会处理它(或者根据文档至少应该如此)

问题出在OverlySystem类中。这是头文件:

class OverlaySystem {
public:
    OverlaySystem();
    Ogre::OverlaySystem* getOverlaySystem() const;
    ~OverlaySystem();

private:
    Ogre::OverlaySystem* overlaySystem;
};
这是源文件:

OverlaySystem::OverlaySystem() :
overlaySystem(new Ogre::OverlaySystem()) {
}

Ogre::OverlaySystem* OverlaySystem::getOverlaySystem() const {
    return this->overlaySystem;
}

OverlaySystem::~OverlaySystem() {
    delete this->overlaySystem;
}
我的理解如下:由于我为Ogre::OverlySystem对象动态分配内存,我必须删除指针以释放分配的内存,这就是我在析构函数中所做的(或者至少我认为我会这样做)

问题是:当我的应用程序关闭时,我在删除Ogre::OverlySystem对象时遇到异常,因为访问冲突表明我在0x00000042位置无法读取。下面是一个失败的例子(对不起德语,但我现在无法改变):

唯一更改的地址是异常地址本身,它是第一个地址


我现在花了几个小时寻找我的失败或失败的原因,但我找不到任何帮助。如果有人能帮我解决这个问题,那就太好了。

找到了错误!我以为我已经做到了,但经过几次改变后,肯定有些混乱

解决方案:
在调用
Ogre::Root
的析构函数之前,必须先调用
Ogre::overlysystem
的析构函数。

我不熟悉该框架,但有一些想法:您是否检查了create方法是否真的返回了有效的非空指针?(我想是的,如果你只是在关闭时出错的话。)你的体系结构中还有什么东西可以删除指针或者接管它的所有权吗?是否存在无法使用
std::unique\u ptr
管理实例的原因?或您是否正在编译一个版本的目标文件,但在项目中的其他地方包含另一个版本的头文件?后者给我带来了一些非常令人困惑的问题,直到我意识到这是一个多么简单的错误。具体来说,如果您(例如,通过不同步所有嵌套的
git
子模块)编译了较新版本的
SomeObject.cpp
,但其他一些源文件
,包括较旧版本的
SomeObject.hpp
,从该源编译的对象文件有可能在
SomeObject
中以错误的偏移量访问members/vptr,这意味着任何事情都可能发生。我看到过瞬间或仅在出口处发生的碰撞;后者令人惊讶,因为它在运行时运行良好,但只在退出时发生故障/终止。也不一致-
gdb
显示了几种不同的故障模式。那是给你的!我打赌你在某处复制了你的
overlysystem
objet。当第一个对象被销毁时,它将
delete
s
Ogre::overlysystem*
和第二个对象销毁
delete
s一个已经删除的指针。因此坠机。请尝试在类中声明私有复制构造函数和赋值运算符。@如果失败,则
new
会引发异常或返回
nullptr
。由于崩溃发生在程序结束时,因此不能考虑异常情况。如果
new
返回
nullptr
失败,
delete nullptr
不会有问题。@YSC:我对
Ogre::overlysystem
对象所做的唯一一件事就是使用:
SceneManager->addRenderQueueListener(overlysystem)将其作为渲染队列侦听器添加到我的
Ogre::SceneManager
我找不到任何相关信息,但这是否意味着在Ogre关闭时删除
Ogre::Root
对象时,
Ogre::overlysystem
get被销毁?如果是这样:为什么像帧侦听器这样的东西在关机时不会被破坏?