【问题标题】:Debug assertion failed - Vector iterator not dereferencable调试断言失败 - 向量迭代器不可取消引用
【发布时间】:2012-07-09 16:30:15
【问题描述】:

运行此代码时出现此运行时错误:

void AlienShipManager::Update(float timeDelta, 
        BulletManager* bulletManager,
        ParticleManager* particleManager,
        GameStringSystem* stringBatch)
{
    unsigned int i = 0;
    while (i < m_alienShipList.size())
    {
        AlienResult result = m_alienShipList[i].Update(timeDelta, bulletManager);
        switch (result)
        {
            case AlienResult::Dead:
                break;
            default:
                break;
        }
            ++i 
    }
}

排队

AlienResult result = m_alienShipList[i].Update(timeDelta, bulletManager);

我如何将 AlienShip 添加到矢量类:

m_alienShipList.push_back(AlienShip(position, speed, m_screeSize, m_alienShipTexture));

如果我有机会,也会出现错误:

AlienShip* newAlien = new AlienShip(position, speed, m_screeSize, m_alienShipTexture);
    m_alienShipList.push_back(*newAlien);
    delete newAlien;

但如果我将其更改为:

AlienShip* newAlien = new AlienShip(position, speed, m_screeSize, m_alienShipTexture);
    m_alienShipList.push_back(*newAlien);

这会导致巨大的内存泄漏。

这是我的 AlienShip 类的外观:

#pragma once

#include "Body.h"
#include "BulletManager.h"
#include "ParticleManager.h"

enum AliensShipState
{
    flying,
    dying,
    dead,
    escaped
};

enum AlienResult
{
    No,
    Hit,
    Dying,
    Dead,
    Escaped
};

class AlienShip : public Body
{
public:
    AlienShip(void);
    AlienShip(float2& position, float2& speed, float2* screenSize, ID3D11Texture2D* alienTexture);
    ~AlienShip(void);

    AlienResult Update(float timeDelta, BulletManager* bulletManager);
    void Draw(BasicSprites::SpriteBatch^ spriteBatch);

protected:
    float m_baseY;
    AliensShipState m_state;
    float2* m_screenSize;
};

AlienShip 类继承自 Body 类,其中包含 Sprite 类,其中包含另一个向量。 但是由于 Sprite 类在其他地方工作得很好,我不认为它是错误的来源。

我想知道为什么会发生这种情况,因为我找不到删除临时对象和损坏向量迭代器之间的关系,如果它完全损坏了。

程序也可以在 Release 中编译和运行,但有一些数据损坏。

我正在使用适用于 Windows 8 的 Visual Studio 2012 Beta。

如果您需要更多源代码,请写。 不幸的是,很难发布所有代码,因为这是一个复杂的程序。

【问题讨论】:

  • 你贴的代码肯定不是原版。缺少;,它不应该编译。您似乎不了解一些基本的C++ 概念,例如内存管理和值语义。此外,这看起来像 C++-cli。
  • BasicSprites::SpriteBatch^ 不是 C++。
  • 症状表明在AlienShip类中的某处违反了“三规则”,但从代码中并不明显。
  • 我删除了 switch 语句中的一些代码,这些代码对向量没有任何作用。 "^" 是 windows 8 中最新的 "Microsoft C++" 中的符号
  • 而且 AlienShip 不需要析构函数或任何 The Tree,因为唯一的指针应该指向同一个位置并且不应该被删除。但是我同意我不了解 C++ 基础知识,因为我只编程了半年

标签: c++ vector


【解决方案1】:

鉴于当您按值将项目添加到向量时它不起作用但是当您泄漏指针时它会起作用,我有 95% 的信心相信您的 AlienShip 的复制构造函数会执行浅拷贝,从而导致您的问题.

编辑:请注意,m_alienShipList.push_back(AlienShip(position, speed, m_screeSize, m_alienShipTexture)); 会复制您的类,如果复制构造函数无法正常工作,它将在以后导致问题。

事实上,如果您粘贴的 AlienShip 定义是正确的,那么实际上只有默认的复制构造函数可能会做错事(您有自己的析构函数这一事实进一步强化了这一点)。

要么实现一个复制构造函数来进行深度复制,要么最好重写你的类以使用 RAII 为你管理内存,以便默认副本是正确的。

【讨论】:

  • 谢谢,我会为它白一个拷贝构造函数和析构函数。但是我仍然不明白为什么我只是在做 m_alienShipList.push_back(AlienShip(position, speed, m_screeSize, m_alienShipTexture)); 时它不起作用。
  • 虽然 push_back 并没有导致复制构造函数启动(只是在想一个普通的复制构造函数)。现在我很确定这就是问题所在。如果有帮助,我现在就让我添加一个复制构造函数
  • 成功了。对不起。我忘记了非常重要的规则,三人组
猜你喜欢
  • 1970-01-01
  • 2014-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多