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

C语言:结构体双指针访问二维数组出现异常问题求助

问题分析与解决

核心问题:局部栈内存回收导致指针悬空

你代码里的v_mtrx(二维数组)和p_v_mtrx(指针数组)都是unity_matrix函数的局部变量,存储在栈内存中。当函数执行完毕返回时,该函数的栈帧会被销毁,这些局部变量占用的内存会被系统回收:

  • 函数内部访问时,栈帧尚未销毁,指针指向的内存有效,因此输出正常;
  • 回到main函数后,原栈内存已被释放或覆盖,m1.pMatrix指向的是无效内存地址,读取到的是垃圾值,导致输出异常。

修复方案:使用动态内存分配

要解决这个问题,需要在堆上分配内存,这类内存不会随函数返回而被回收。修改后的代码如下:

#include <stdio.h>
#include <stdlib.h>

struct Matrix
{
    int rows;
    int cols;
    double **pMatrix;
};

struct Matrix unity_matrix(int row, int col);

int main()
{
    int row = 10, col = 10;
    struct Matrix m1 = unity_matrix(row, col);
    for (int x = 0; x < row; x++)
    {
        printf("\nOutside result %d\n", x);
        for (int y = 0; y < col; y++)
        {
            printf("%lf ", m1.pMatrix[x][y]);
        }
    }

    printf("\n Rows = %d Cols = %d", m1.rows, m1.cols);

    // 释放动态分配的内存,避免内存泄漏
    for (int i = 0; i < row; i++)
    {
        free(m1.pMatrix[i]);
    }
    free(m1.pMatrix);

    return 0;
}

struct Matrix unity_matrix(int row, int col)
{
    // 分配指针数组的内存
    double **p_v_mtrx = (double**)malloc(row * sizeof(double*));
    if (p_v_mtrx == NULL) {
        struct Matrix empty = {0, 0, NULL};
        return empty;
    }

    // 为每一行分配内存
    for (int i = 0; i < row; i++)
    {
        p_v_mtrx[i] = (double*)malloc(col * sizeof(double));
        if (p_v_mtrx[i] == NULL) {
            // 分配失败时,释放已分配的内存
            for (int j = 0; j < i; j++) {
                free(p_v_mtrx[j]);
            }
            free(p_v_mtrx);
            struct Matrix empty = {0, 0, NULL};
            return empty;
        }
    }

    // 填充矩阵值
    for (int x = 0; x < row; x++)
    {
        for (int y = 0; y < col; y++)
        {
            p_v_mtrx[x][y] = x + y + 1.0;
        }
    }

    struct Matrix mtrx = {row, col, p_v_mtrx};

    // 内部验证输出
    for (int x = 0; x < row; x++)
    {
        printf("\nInside result %d\n", x);
        for (int y = 0; y < col; y++)
        {
            printf("%lf ", mtrx.pMatrix[x][y]);
        }
    }

    return mtrx;
}

额外说明

  • 动态分配的内存必须手动调用free释放,否则会造成内存泄漏;
  • 可以用calloc替代malloc,它会自动将内存初始化为0,更适合矩阵初始化场景;
  • 内存分配失败的处理逻辑不可缺少,能避免程序崩溃。

内容的提问来源于stack exchange,提问作者pasty guacamole

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 17:14:50