C++初学者疑问:while(true)循环中动态内存分配为何异常?
问题分析
你的代码无法正常运行的核心原因是悬空指针引发的未定义行为:
- 全局变量
grid一开始被分配了new string*[gridRows]的顶层内存。 - 第一次循环调用
CleanGrid时,最后执行的delete[] grid;直接释放了顶层内存,但grid本身仍保留着原内存地址(变成悬空指针)。 - 第二次进入循环调用
InitGrid时,你尝试通过这个悬空指针给grid[i]赋值,属于访问已释放的内存,直接触发程序崩溃。
修正方案
方案1:仅释放行内存,保留顶层全局指针
既然grid是全局分配的顶层指针,就不要在循环内释放它,只需要清理每一行的内存:
#include <iostream> using namespace std; const int gridRows = 3; const int gridColumns = 3; string **grid = new string *[gridRows]; void InitGrid(string **grid, const int &rows, const int &columns); void CleanGrid(string **grid, const int &rows, const int &columns); int main() { while (true) { InitGrid(grid, gridRows, gridColumns); // some code CleanGrid(grid, gridRows, gridColumns); } // 程序结束前释放顶层指针(死循环场景下不会执行,但属于良好编程习惯) delete[] grid; return 0; } void InitGrid(string **grid, const int &rows, const int &columns) { for (int i = 0; i < rows; i++) { grid[i] = new string[columns]; for (int j = 0; j < columns; j++) { grid[i][j] = "[ ]"; } } } void CleanGrid(string **grid, const int &rows, const int &columns) { for (int i = 0; i < rows; i++) { delete[] grid[i]; // 可选:将行指针置空,避免后续误操作 grid[i] = nullptr; } // 删除原有的顶层内存释放语句:delete[] grid; }
方案2:循环内完整分配/释放所有内存
把grid的生命周期限制在单次循环内,每次循环重新分配顶层指针:
#include <iostream> using namespace std; const int gridRows = 3; const int gridColumns = 3; void InitGrid(string **grid, const int &rows, const int &columns); void CleanGrid(string **grid, const int &rows, const int &columns); int main() { while (true) { string **grid = new string *[gridRows]; InitGrid(grid, gridRows, gridColumns); // some code CleanGrid(grid, gridRows, gridColumns); } return 0; } void InitGrid(string **grid, const int &rows, const int &columns) { for (int i = 0; i < rows; i++) { grid[i] = new string[columns]; for (int j = 0; j < columns; j++) { grid[i][j] = "[ ]"; } } } void CleanGrid(string **grid, const int &rows, const int &columns) { for (int i = 0; i < rows; i++) { delete[] grid[i]; } delete[] grid; }
方案3:用标准容器替代手动内存管理(最推荐)
作为初学者,手动管理动态内存极易出错,C++标准库的vector可自动处理内存分配与释放,代码更简洁安全:
#include <iostream> #include <vector> using namespace std; const int gridRows = 3; const int gridColumns = 3; void InitGrid(vector<vector<string>> &grid); int main() { while (true) { vector<vector<string>> grid(gridRows, vector<string>(gridColumns)); InitGrid(grid); // some code // 无需手动清理,vector会自动释放内存 } return 0; } void InitGrid(vector<vector<string>> &grid) { for (auto &row : grid) { for (auto &cell : row) { cell = "[ ]"; } } }
内容的提问来源于stack exchange,提问作者iesnihS
相关产品推荐
相关产品推荐

