C语言使用realloc调整矩阵大小触发异常的问题求助
矩阵重分配代码崩溃的原因及修复方案
核心崩溃原因
触发异常的代码newMatrix = realloc(matrix, sizeof(int *)**m);有两个致命问题:
- 运算符优先级错误:
**m是对指针m做两次解引用,而m是int*类型,第二次解引用会直接访问非法内存地址,导致程序崩溃。正确写法是sizeof(int*) * (*m)——用*m获取新行数,再乘以每个行指针的大小,加括号避免优先级坑。 - 另外,你在输入新尺寸后直接修改了
*m,但后续操作依赖原行数的逻辑完全缺失,这也是隐藏的崩溃诱因。
其他必修复的隐藏问题
除了直接崩溃的原因,代码里还有一堆会导致内存泄漏、野指针或越界访问的问题:
- createMatrix列分配错误:分配每一行内存时用了
malloc(m*sizeof(int)),但这里应该用列数n,否则行列数不同时会分配错误的内存大小,后续赋值/打印会越界。 - 矩阵调整循环范围错误:重分配列的循环
for(l=0; l<*n; ++l)循环的是列数,但实际要循环行数*m——循环列数要么漏处理行,要么访问超出数组的指针,必然崩溃。 - 新增行未初始化:如果新行数比原行数多,realloc新增的行指针是野指针,直接realloc会触发未定义行为,必须给新行单独分配内存。
- 缩小行数时内存泄漏:新行数比原行数少时,原多余的行没有被free,会一直占用内存。
- menu函数参数传递错误:menu的
m和n是传值参数,你传递&m、&n是取menu局部变量的地址,main里的矩阵尺寸永远不会更新,后续操作全是错的。 - realloc失败时内存泄漏:realloc返回NULL时直接返回NULL,原矩阵的内存会彻底丢失,造成泄漏。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <time.h> void printMatrix(int** p, int m, int n); int** createMatrix(int m, int n); void obtainMatrixDim(int* m, int* n); void printOptnMenu(); int** optionsMenuSwitch(int op, int** matrix, int* m, int* n); void menu(int** matrix, int* m, int* n); // 修改为指针参数 int main() { int** matrix, m, n; obtainMatrixDim(&m, &n); matrix = createMatrix(m, n); menu(matrix, &m, &n); // 传递m、n的地址 // 退出前释放所有内存 for (int i = 0; i < m; i++) { free(matrix[i]); } free(matrix); return 0; } void obtainMatrixDim(int* m, int* n) { printf("Provide the number of rows of the Matrix:\t"); scanf("%d", m); printf("Provide the number of columns of the Matrix:\t"); scanf("%d", n); } int** createMatrix(int m, int n) { int** matrix, i, j; srand((unsigned)time(NULL)); matrix = (int**)malloc(m * sizeof(int*)); if (matrix == NULL) { printf("Memory allocation failed for rows\n"); return NULL; } for (i = 0; i < m; i++) { matrix[i] = (int*)malloc(n * sizeof(int)); // 改为用n分配列内存 if (matrix[i] == NULL) { // 分配失败时回滚已分配内存 for (int k = 0; k < i; k++) { free(matrix[k]); } free(matrix); printf("Memory allocation failed for columns\n"); return NULL; } } for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { matrix[i][j] = rand() % 999 + 1; } } return matrix; } // 改为指针参数,确保main里的尺寸能被更新 void menu(int** matrix, int* m, int* n) { int op; do { printOptnMenu(); scanf("%d", &op); int** temp = optionsMenuSwitch(op, matrix, m, n); if (temp != NULL) { matrix = temp; } } while (op != 3); } void printOptnMenu() { printf("\nSelect an option:\n"); printf("1.Resize the Matrix\n"); printf("2.Print the Matrix\n"); printf("3.Exit\n"); printf("\t:"); } int** optionsMenuSwitch(int op, int** matrix, int* m, int* n) { int old_rows = *m; int** newMatrix = matrix; switch (op) { case 1: { int new_rows, new_cols; printf("\nProvide the new size of rows and columns, in that order.\n"); printf("If you reduce the size you will lose information.\n"); printf("Rows:"); scanf("%d", &new_rows); printf("\nColumns:"); scanf("%d", &new_cols); // 重分配行指针数组 newMatrix = realloc(matrix, sizeof(int*) * new_rows); if (newMatrix == NULL) { printf("Failed to reallocate rows\n"); return matrix; // 返回原矩阵,避免丢失指针 } // 处理新增行:分配列内存并赋值 if (new_rows > old_rows) { for (int l = old_rows; l < new_rows; l++) { newMatrix[l] = malloc(sizeof(int) * new_cols); if (newMatrix[l] == NULL) { printf("Failed to allocate new columns\n"); // 回滚已分配的新行 for (int k = old_rows; k < l; k++) { free(newMatrix[k]); } *m = old_rows; return matrix; } // 给新行赋随机值 for (int j = 0; j < new_cols; j++) { newMatrix[l][j] = rand() % 999 + 1; } } } // 调整原有行的列大小 int loop_count = new_rows < old_rows ? new_rows : old_rows; for (int l = 0; l < loop_count; l++) { int* temp_col = realloc(newMatrix[l], sizeof(int) * new_cols); if (temp_col == NULL) { printf("Failed to reallocate columns for row %d\n", l); // 回滚新增行(如果有的话) if (new_rows > old_rows) { for (int k = old_rows; k < new_rows; k++) { free(newMatrix[k]); } free(newMatrix); } *m = old_rows; return matrix; } newMatrix[l] = temp_col; } // 处理缩小行数:释放多余行的内存 if (new_rows < old_rows) { for (int l = new_rows; l < old_rows; l++) { free(newMatrix[l]); } } // 更新矩阵尺寸 *m = new_rows; *n = new_cols; return newMatrix; break; } case 2: { printMatrix(newMatrix, *m, *n); return newMatrix; break; } case 3: { printf("\n<<< Bye >>>"); return newMatrix; break; } default: printf("Please select a valid menu option.\n"); return newMatrix; break; } } void printMatrix(int** p, int m, int n) { printf("\nThe created matrix is:\n\n"); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { printf(" %d ", p[i][j]); } printf("\n"); } printf("\n"); }
修复要点总结
- 修正
sizeof(int *)**m为sizeof(int*) * (*m),避免非法内存访问; - createMatrix里用列数
n分配每行内存; - 调整矩阵时循环行数而非列数;
- 新增行时分配列内存,缩小行时释放多余行;
- menu函数传递m、n的指针,确保尺寸能正确更新;
- 处理realloc失败的情况,避免内存泄漏和指针丢失;
- 程序退出前释放所有动态分配的内存。
内容的提问来源于stack exchange,提问作者Vlad GAG
相关产品推荐
相关产品推荐

