析构函数调用删除函数时程序崩溃

时间:2013-08-07 18:35:38

标签: c++ destructor

当调用析构函数时,我正在处理大型代码并且程序崩溃。我指的是失败的地方:

Application::~Application()
{
  for ( int blockId=0; blockId< m_noBlocks; blockId++ ) {
    if ( m_blocks[ blockId ] ) {
      delete m_blocks[ blockId ];  //error here
      m_blocks[ blockId ] = NULL;
    }
    if ( m_methods[ blockId ] ) {
      delete m_methods[ blockId ];
      m_methods[ blockId ] = NULL;
    }
  }
}

程序在'error here'中提到的删除操作时完全崩溃。但是,如果我评论该行,该程序似乎工作正常。有人会抛光,可能是什么问题?

编辑: 它们使用new在构造函数中分配。 m_noBlocks使用值定义,但未在此处指定:

Application::Application(){
      m_blocks = new ZFSBlock*[m_noBlocks];
      m_methods = new ZFSMethods*[m_noBlocks];

      for ( int blockId=0; blockId< m_noBlocks; blockId++ ) {
        m_methods[ blockId ] = NULL;
        m_blocks[ blockId ] = NULL;
      }
}

但是,稍后会在代码的主要部分中实际分配m_methodsm_blocks

3 个答案:

答案 0 :(得分:2)

m_noBlocks未初始化,因此没有人可以预测您有多少指针存储空间。

答案 1 :(得分:0)

假设您的代码与此类似:

class Application
{
private:
    int m_noBlocks;
    struct ZFSBlock
    {
        int a;
    };
    struct ZFSMethods
    {
        int a;
    };
    ZFSBlock **m_blocks;
    ZFSMethods **m_methods;
public:
    Application();
    ~Application();
};

Application::Application()
{
    m_noBlocks = 5;
    m_blocks = new ZFSBlock*[m_noBlocks];
    m_methods = new ZFSMethods*[m_noBlocks];
    for(int i = 0; i < m_noBlocks; i++)
    {
        m_blocks[i] = new ZFSBlock[486]; //random number
        m_methods[i] = new ZFSMethods[156];
    }
}

然后你应该删除:

Application::~Application()
{
  for ( int blockId=0; blockId< m_noBlocks; blockId++ ) {
    if ( m_blocks[ blockId ] ) {
      delete [] m_blocks[ blockId ]; //needs "delete []" because I used "new ZFSBlock[486];",
      m_blocks[ blockId ] = NULL;    //not "new ZFSBlock"
    }
    if ( m_methods[ blockId ] ) {
      delete [] m_methods[ blockId ];
      m_methods[ blockId ] = NULL;
    }
  }
  //Also don't forget to delete double pointers:
  if ( m_methods ) {
      delete [] m_methods;
      m_methods = NULL;
    }
  if ( m_methods ) {
      delete [] m_methods;
      m_methods = NULL;
    }
}

答案 2 :(得分:0)

嗯,这些只是猜测,但是因为猜测是允许的:一个 数组中的指针未分配new或它 分配了一个数组new(例如new ZFSBlock[n])。或者你可以把相同的指针放两次。

如果对象是可复制的,并且只有一个对象 在每个插槽中,您应该使用std::vector<ZFSBlock>std::vector<ZFSMethods>,而不是指针数组。 这将自动处理所有问题,并且 为您节省大量的工作。 (您也可以考虑使用单个 带有包含两个元素的结构的向量,如果是向量 条目是严格的一对一关系。)

如果每个插槽中有多个对象(即您正在使用 new [],它解释了崩溃),然后是最好的解决方案 将是std::vector<std::vector<ZFSBlock>>std::vector<std::vector<ZFSMethod>>(或单身 std::vector<std::vector<TheStruct>>)。