【问题标题】:why is deleting this object causing problems?为什么删除此对象会导致问题?
【发布时间】:2012-01-05 14:08:47
【问题描述】:

实例化:

weapons.push_back(new Pistol());
weapons.push_back(new Rifle());
weapons.push_back(new Shotgun());

析构函数,当第一次删除发生时,代码中断。当我关闭程序时会发生这种情况。

Brain::~Brain()
{
    for (unsigned int i = 0; i < weapons.size(); i++)
    {
        delete weapons[i]; // this is where the code breaks
    }
}

我收到警告:

Unhandled exception at 0x0096371f in D3D10DEMO.exe: 0xC0000005: Access violation reading location   0x000002ce.

武器是这样的:

weapons(vector<Gun*>())

编辑 - 我已经从这个问题中删除了大部分代码,但我也削减了我的程序,以便在此处以更小的解决方案重现问题:

http://dl.dropbox.com/u/13519335/D3D10DEMO_0.25.MinRep.zip

【问题讨论】:

  • 我们需要Brain的定义。
  • 过去的批评不是你没有提供你所拥有的一切,而是你没有以简洁和独立的方式提出问题。还是不行……
  • 一个 23,813,003 字节的压缩包?我们需要的文件:hcppslnvprojvcxproj.*suo。我们不需要的文件:ipchlastbuildstatemanifestobjpdbsdflogtlogidb。删除这些会减少到 67,724 字节。更易于管理。下载速度也快了 351 倍。

标签: c++ winapi


【解决方案1】:

你还没有为你的武器类定义虚拟析构函数。 http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7

【讨论】:

  • 是否需要从派生析构函数的实现中调用基析构函数?
  • 不要调用基础析构函数。 stackoverflow.com/questions/677620/…
  • Gun 类继承自 GameObject。它有虚拟析构函数吗?
  • 现在可以了,但问题仍然存在。我将在我的问题中更新调用堆栈的输出
  • 关于那个实体类。它有虚拟会员吗?还有虚拟析构函数?
【解决方案2】:

你的问题是定义

class Brain : public Entity
{
private:
    std::vector<Gun*> weapons;

以及Brain对象对Gun*的所有权。

Brain::~Brain()
{
    for (unsigned int i = 0; i < weapons.size(); i++)
    {
        delete weapons[i];
    }
}

如果一个 Brain 是副本构造的,删除将被多次调用,从不同的武器向量中删除相同的 Gun。当您在主函数中添加代理(代理是 Brain 的派生类)时,会创建一个临时大脑。

int main()
{
    Level* level;
std::vector<Agent> agents;

level = new Level(agents);

for (int i = 0; i < 1; i++)
    {
        //TODO - health is a pointless parameter here
        agents.push_back(Agent(100, *level, agents, level->Pickups(), D3DXCOLOR(1.0F, 0.4f, 0.4f, 1.0f)));
    }

delete level;

}

 如果你为 Brain 实现了一个复制构造函数来克隆 Gun* 向量,你应该没问题。或者你应该在你的向量中使用shared_ptr&lt;Gun&gt;,这样你就不必删除它们了。

总结你的问题归结为

class Foo{};

class Bar
{
public:
    Bar()
    {
        mFooVec.push_back( new Foo() );
        mFooVec.push_back( new Foo() );
    }

    ~Bar()
    {
        for( unsigned int i = 0;i < mFooVec.size(); ++i )
        {
            delete mFooVec[i];
        }
    }

    std::vector<Foo*> mFooVec;
};

int main()
{
    Bar x;
    Bar y = x;

    return 0;
}

这里 Bar x 和 y 在它们的 mFooVec

中都有相同的两个 Foo*

【讨论】:

  • 所以指针指向所有类中的相同对象。但是也有更多的指针,对吧?它们都指向同一个东西,但实际上不同的类中有不同的指针,是吗?
  • 什么是可取的?复制构造函数还是共享指针?
  • @SirYakalot:不管有没有拷贝构造函数,都使用std::vector&lt;std::shared_ptr&lt;Gun&gt;&gt; weapons;,不要删除Gun指针。
  • @sad_man 你能告诉我一些关于共享指针的信息以及为什么它们不需要被删除吗?另外,对不起,你很伤心。
  • @SirYakalot:它是一个智能指针,会自动删除它拥有的指针。阅读this
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多