1

每当调试器命中操作符时,以下代码似乎会导致堆损坏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;
}

过去几天我在论坛上搜索了各种堆损坏主题,到目前为止,我已经尝试了各种尝试。

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

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

4

1 回答 1

1

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

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

我要做的另一件事是确保在删除 tile_array 之后以及声明它时将其设为 NULL。如果执行此操作后问题消失,则实际上是删除太早(在初始化之前)或删除太多。

您要仔细检查的最后一件事是没有缓冲区溢出/不足。new[] 运算符将一些元数据放在堆上,delete[] 运算符使用这些元数据来了解数组的大小,以便它可以正确清理内存。损坏此元数据可能会导致堆损坏。

于 2012-09-08T00:34:06.283 回答