You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言使用realloc调整矩阵大小触发异常的问题求助

矩阵重分配代码崩溃的原因及修复方案

核心崩溃原因

触发异常的代码newMatrix = realloc(matrix, sizeof(int *)**m);有两个致命问题:

  • 运算符优先级错误:**m是对指针m做两次解引用,而m是int*类型,第二次解引用会直接访问非法内存地址,导致程序崩溃。正确写法是sizeof(int*) * (*m)——用*m获取新行数,再乘以每个行指针的大小,加括号避免优先级坑。
  • 另外,你在输入新尺寸后直接修改了*m,但后续操作依赖原行数的逻辑完全缺失,这也是隐藏的崩溃诱因。

其他必修复的隐藏问题

除了直接崩溃的原因,代码里还有一堆会导致内存泄漏、野指针或越界访问的问题:

  1. createMatrix列分配错误:分配每一行内存时用了malloc(m*sizeof(int)),但这里应该用列数n,否则行列数不同时会分配错误的内存大小,后续赋值/打印会越界。
  2. 矩阵调整循环范围错误:重分配列的循环for(l=0; l<*n; ++l)循环的是列数,但实际要循环行数*m——循环列数要么漏处理行,要么访问超出数组的指针,必然崩溃。
  3. 新增行未初始化:如果新行数比原行数多,realloc新增的行指针是野指针,直接realloc会触发未定义行为,必须给新行单独分配内存。
  4. 缩小行数时内存泄漏:新行数比原行数少时,原多余的行没有被free,会一直占用内存。
  5. menu函数参数传递错误:menu的m和n是传值参数,你传递&m、&n是取menu局部变量的地址,main里的矩阵尺寸永远不会更新,后续操作全是错的。
  6. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 08:15:38