0

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

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;
    }
  }
}

该程序完全在“错误此处”中提到的删除操作处崩溃。但是,如果我评论该行,该程序似乎工作正常。有人可以扔灯吗,可能是什么问题?

编辑:它们在构造函数中使用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_methods实际分配。m_blocks

4

3 回答 3

2

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

于 2013-08-07T18:50:57.793 回答
0

好吧,这些只是猜测,但由于猜测是允许的:数组中的一个指针没有分配给new,或者它分配给了一个数组new(例如,类似的东西new ZFSBlock[n])。或者您可以将相同的指针放入两次。

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

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

于 2013-08-07T19:10:08.370 回答
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;
    }
}
于 2013-08-07T19:09:40.773 回答