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

使用单次malloc分配的二维数组如何初始化和访问数组成员

单malloc分配二维数组的访问与内存结构说明

访问与初始化方法

你提到的array[0] + (char *)1写法是错误的:一方面int*类型指针和char*类型指针直接相加属于非法运算,另一方面int类型通常占4字节(依平台而定),仅偏移1字节只会取到单个int元素的部分字节,无法得到正确的array[0][1]的值。

正确的访问方式非常简单,直接使用二维数组下标即可,array[i][j]就代表第i行第j列的元素,也可以用等价的指针写法*(array[i] + j),两种写法效果完全一致。

初始化和访问的完整示例代码如下:

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

int main() {
    size_t i, j;
    unsigned int nrows = 2;
    unsigned int ncolumns = 3;
    int **array;
    const size_t row_pointers_bytes = nrows * sizeof *array;
    const size_t row_elements_bytes = ncolumns * sizeof **array;
    array = malloc(row_pointers_bytes + nrows * row_elements_bytes);
    if (array == NULL) {
        perror("内存分配失败");
        return 1;
    }

    int * const data = array + nrows;
    for(i = 0; i < nrows; i++) {
        array[i] = data + i * ncolumns;
    }

    // 初始化数组元素
    for (i = 0; i < nrows; i++) {
        for (j = 0; j < ncolumns; j++) {
            array[i][j] = i * 10 + j;
        }
    }

    // 遍历访问元素
    for (i = 0; i < nrows; i++) {
        for (j = 0; j < ncolumns; j++) {
            printf("array[%zu][%zu] = %d\t地址:%p\n", i, j, array[i][j], &array[i][j]);
        }
    }

    free(array);
    return 0;
}

如果你确实需要按字节偏移访问元素,正确写法为*(int*)((char*)array[0] + sizeof(int) * 1),但该写法可读性差易出错,日常开发不推荐使用。

内存结构图示

你通过单malloc申请的是一块连续的内存空间,整体分为两个区域:

  1. 行指针区:长度为nrows * sizeof(int*),用来存储每行元素的首地址,也就是array[0]、array[1]的存储位置
  2. 数据存储区:紧跟在行指针区之后,长度为nrows * ncolumns * sizeof(int),按行优先的顺序存储所有数组元素

以32位系统(指针和int都占4字节)、malloc返回的起始地址为0x1000为例,内存布局如下:

内存地址存储内容
0x1000array[0]的值:0x1008(第一行元素首地址)
0x1004array[1]的值:0x1014(第二行元素首地址)
0x1008array[0][0]
0x100Carray[0][1]
0x1010array[0][2]
0x1014array[1][0]
0x1018array[1][1]
0x101Carray[1][2]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:24:03