删除全局数组时堆损坏

时间:2012-09-08 00:09:22

标签: c++ arrays winapi delete-operator heap-corruption

以下代码似乎在调试器命中delete[]运算符时导致堆损坏。它试图删除在头文件中定义为extern的全局结构数组,然后在主.cpp文件的全局范围内声明。

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ 
  switch(msg) 
  { 
    case WM_CREATE: 
      { 
        int main_win_x, main_win_y;

        tiles_horiz = 10;  //temp code
        tiles_vert = 10;   //temp code
        num_mines = 5;    //temp code

        main_win_x = (tiles_horiz * 22) + 20;
        main_win_y = (tiles_vert * 22) + 20;

        MoveWindow(hwnd, 100, 100, main_win_x, main_win_y, TRUE);

        tiles_total = (tiles_horiz * tiles_vert);
        tile_array = new tile[tiles_total];

        SetupPlayField();
        DrawInitTiles(hwnd);
      }
      break;
    case WM_SIZE:
      {

      }
      break;
    case WM_CLOSE:
      delete[] tile_array;
      DestroyWindow(hwnd);
      break;
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hwnd, msg, wParam, lParam);
  }
  return 0;
}

我在最近几天在论坛上搜索了各种堆损坏主题,到目前为止已经尝试了各种各样的事情。

有人建议,当程序点击delete[]时,指向我的数组tile_array的指针可能已经改变了。但我已经检查了几次,指针和数组的第一个元素的地址保持不变。

来自其他人帖子的其他论坛回答通常表明我可能会多次删除该数组,但到目前为止,这是delete[]运算符用于该特定数组的唯一时间。

1 个答案:

答案 0 :(得分:1)

在不知道对title_array的每次访问的情况下,很难推测出这个问题的原因。程序显示的内存损坏并不总是导致它的原因。

您可能要检查的一件事是extern声明是针对“tile * tile_array”而不是“tile tile_array []”。我非常怀疑这种情况,但在处理extern和数组时,我已经看到这个错误咬了几个人。

我要做的另一件事是确保在删除tile_array并将其声明后将其清空。如果在执行此操作时问题消失,那么实际上要么是过早删除(在初始化之前),要么删除太多。

您要仔细检查的最后一件事是没有缓冲区上/下运行。 new []运算符在堆上放置一些元数据,delete []运算符用它来知道数组的大小,以便它可以正确地清理内存。破坏此元数据可能会导致堆损坏。