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

使用memcpy复制二维数组触发段错误的原因咨询

二维数组memcpy操作导致段错误的原因分析

我正在学习二维数组的操作以及memcpy的使用,编写了如下的array_test测试函数:

void array_test(void)
{
    int arr[3][5] = {{0, 1, 1, 0, 1}, {1, 1, 1, 1, 1}, {1, 0, 0, 1, 0}};
    for (size_t i = 0; i < 3; i++) {
        for (size_t j = 0; j < 5; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    int row = 3;
    int col = 5;
    int **arr2 = (int **)malloc(sizeof(int *) * row);
    if (!arr2) {
        printf("arr2 malloc failed\n");
        exit(-1);
    }
    memset(arr2, 0, sizeof(int *) * row);
    for (int i = 0; i < row; i++) {
        arr2[i] = (int *)malloc(sizeof(int) * col);
        if (!arr2[i]) {
            printf("arr2[%d] malloc failed\n", i);
            exit(-1);
        }
        memset(arr2[i], 0, sizeof(int) * col);
    }
    for (size_t i = 0; i < 3; i++) {
        for (size_t j = 0; j < 5; j++) {
            printf("%d ", arr2[i][j]);
        }
        printf("\n");
    }

    memcpy(arr2, arr, sizeof(int) * 3 * 5);
    for (size_t i = 0; i < 3; i++) {
        for (size_t j = 0; j < 5; j++) {
            printf("%d ", arr2[i][j]);
        }
        printf("\n");
    }
}

执行上述代码后,原本预期复制成功,却出现了如下段错误:

0 1 1 0 1
1 1 1 1 1
1 0 0 1 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
Segmentation fault

问题原因

核心问题是栈上二维数组和堆上指针数组的内存布局完全不同,直接用memcpy批量复制会彻底破坏指针数组的结构:

  • arr是栈上的二维数组,内存是连续的整块区域,15个int按行依次排列,没有额外的指针存储。
  • arr2是指针数组:先分配了3个int*的空间用来存储行指针,每个指针又指向堆上独立的5个int空间。也就是说arr2本身只存储3个指针,真正的数据分散在堆的不同位置。

执行memcpy(arr2, arr, sizeof(int)*3*5)时:

  1. 首先会把arr里的前几个int值覆盖arr2的指针区域(比如64位系统中,3个指针占24字节,对应6个int),把原本指向有效堆内存的指针改成了arr里的0、1这类无效地址,变成野指针。
  2. 其次,arr2本身只分配了3个指针的空间(24字节),但你要复制60字节(15*4),属于越界写入,会破坏堆内存的管理结构。

后续通过arr2[i][j]访问时,本质是用被篡改的野指针去寻址,直接触发段错误。

正确的复制方式

应该逐行复制,针对每个行指针指向的内存单独拷贝:

for (int i = 0; i < row; i++) {
    memcpy(arr2[i], arr[i], sizeof(int) * col);
}

这样既不会破坏arr2的指针结构,也能正确把arr的每一行数据复制到对应堆内存中。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:42:41