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

C语言中通过指针赋值访问二维数组失败,打印触发段错误

为什么二维数组赋值给int**会触发段错误?

我来帮你把这个问题的来龙去脉讲清楚,顺便给你几种解决办法~

首先先确认你的问题场景:你在函数里定义了一维数组singleArray和二维数组dualArray,用int*接收一维数组后遍历打印完全正常,但把二维数组赋值给int**后遍历就触发了段错误。

核心原因:类型不匹配!

先看一维数组的正常逻辑

int singleArray[]={1,2,3}在内存里是连续存储的3个int值:1 → 2 → 3。当你写int* sa = singleArray时,数组名singleArray会隐式转换为指向第一个元素的指针(类型是int*),和sa的类型完全匹配。遍历sa[i]本质是*(sa + i),也就是从首地址偏移i个int的位置取值,完全合法。

再看二维数组的错误根源

int dualArray[2][2]的内存布局是连续的4个int:1 → 2 → 3 → 4,它的类型是int [2][2]。当你试图把它赋值给int** da时,这里就出现了类型不兼容的问题:

  • int**是指向int指针的指针,它期望指向的内存里存储的是一个个int*类型的地址;
  • 但二维数组名dualArray转换后是指向一维数组的指针(类型是int (*)[2],即指向长度为2的int数组的指针),它指向的内存里直接存储的是int值(也就是1、2这些数据)。

当你用da[i][j]遍历的时候,编译器会解析成*( *(da + i) + j ):先取da+i指向的内容(期望是一个int*地址),然后再偏移j取int值。但实际上da指向的是二维数组的首地址,这里的内容是1和2,把1当作一个内存地址去解引用,自然会访问非法内存,触发段错误。

解决办法

方法1:修改函数参数,匹配二维数组的真实类型

这是最直接、最推荐的方式,让函数参数的类型和二维数组一致。如果列数固定,可以这么写:

void printOutput(int array[][2], int row) {
    int i = 0, j = 0;
    for (i = 0; i < row; i++) {
        for (j = 0; j < 2; j++) {
            printf("%d ", array[i][j]);
        }
        printf("\n");
    }
}

// 调用时直接传dualArray
printOutput(dualArray, 2);

如果想支持可变列数(C99及以后标准支持可变长度数组),可以改成:

void printOutput(int row, int col, int array[row][col]) {
    int i = 0, j = 0;
    for (i = 0; i < row; i++) {
        for (j = 0; j < col; j++) {
            printf("%d ", array[i][j]);
        }
        printf("\n");
    }
}

// 调用
printOutput(2, 2, dualArray);

方法2:手动构建指针数组适配int**类型

如果你一定要用int**作为函数参数,可以先创建一个指针数组,让每个元素指向二维数组的每一行,再把这个指针数组传给函数:

// 定义指针数组,每个元素指向dualArray的一行
int* da_ptr[2];
da_ptr[0] = dualArray[0];
da_ptr[1] = dualArray[1];

// 现在da的类型是int**,可以正常传入printOutput
int** da = da_ptr;
printOutput(da, 2, 2);

方法3:把二维数组当作一维数组访问(原理向)

因为二维数组在内存里是连续存储的,你也可以直接用int*来遍历,本质是跳过二维的语法糖直接操作连续内存:

int* da = (int*)dualArray;
printf("二维数组内容:\n");
for (int i = 0; i < 2*2; i++) {
    printf("%d ", da[i]);
    if ((i+1) % 2 == 0) printf("\n");
}

总结

记住一个关键点:C语言里的二维数组≠int**指针!一维数组可以隐式转换为int*,但二维数组转换后是指向一维数组的指针,两者的内存语义完全不同,强行赋值必然会导致内存访问错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:25:10