C语言malloc申请的连续内存为何可以直接用数组下标进行偏移?偏移量是怎么被确定的?

AdianGg
  • 8

问题来源

是我本人在使用C语言完成顺序线性表时一个比较疑惑的问题,可能题目描述的不是很清楚,下面我将详细的描述我的问题

问题描述

首先我定义了一个.h文件来定义我的顺序表结构

// 假定该顺序表数据元素类型为Int,实际上可以是任何数据类型
typedef int Element;
// 定义顺序表结构体
typedef struct{
    Element *head;
    int length; // 顺序表当前已使用的长度
    int size;     // 顺序表的最大长度(maxsize)
}sequence_list;

在调用该.h文件后,我编写了一个函数用于初始化顺序表

void InitList(sequence_list *sequenceList,int size){
    // init the sequence_list
    sequenceList->size = size;
    sequenceList->length = 0;
    sequenceList->head = (Element*)malloc(sizeof(Element) *sequenceList->size);
}

这里我使用malloc申请了动态内存,所以基本上来说,就是我申请出了一块连续内存
内存首地址为head,长度为size * 长度数据元素长度,取到每一个对应的值完全依赖首地址内存+偏移量

这个时候问题来了,我使用数组下标就可以像int数组一样,直接偏移到想要的位置

void PrintList(sequence_list *sequenceList){
    // print all element
    for (int i = 0;i < sequenceList->length;i++){
        printf("%d \t",sequenceList->head[i]);
    }
    printf("\n");
}

我很好奇这个数组下标是如何判断出应该偏移多少位的,正常int数组在声明时声明了类型,因此编译器知道需要偏移的大小是多少,那么这样malloc申请的连续地址,这个数组下标又是怎么知道单个数据元素需要的内存大小是多少?这是怎么确定偏移量的?

回复
阅读 326
1 个回答
xdsnet
  • 7.4k
✓ 已被采纳

关键的就是这一步:

sequenceList->head = (Element*)malloc(sizeof(Element) *sequenceList->size);

这里, 确定了申请的内存大小,也确定了后续使用内存的基本规则。
sizeof(Element) *sequenceList->size 这里确定了内存申请的量,首先,通过sizeof(Element) 获取了单个Element的大小,再乘以需要的数量(由sequenceList->size确定),就是总的大小。这样malloc函数申请的就是合适的总大小啦。

至于如何用内存,这里用了(Element*)malloc(sizeof(Element) *sequenceList->size) ,就是说强制以(Element*)Element结构的形式来访问申请到的内存。有了这一步后,后面访问就直接可以类似数组,每次偏移会自动的以Element结构所占内存字节数的整数倍来移动指针啦,即后面sequenceList->head[i]对应的就是 (Element*)(sequenceList->head +sizeof(Element) *i) ,即数据结构按Element解析。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏