在C语言中,使用malloc
函数创建动态数组,使用一个指针指向它,使用下标进行访问。
unsigned long *a = (unsigned long *)malloc(2 * sizeof(int));
a[0] = 1000;
a[1] = 2000;
printf("%d %d\n", a[0], a[1]);
free(a);
上述例子,申请了两个int空间的动态数组,使用int *
指向它,使用a[0],a[1]
访问,这与数组访问一样,区别就是动态申请内存在堆空间,还需要使用free
进行释放,而一般的数组在栈空间,自动释放。
这个很容易,这里想延申类比一下,这是Liunx 0.11内核类似的一段代码很有趣。
#include <stdio.h>
#include <stdlib.h>typedef struct desc_struct
{ unsigned long a, b;
}
desc_table[256];desc_table idt, gdt;void set_gate(unsigned long *gate_addr) {gate_addr[0] = 100;gate_addr[1] = 200;
}int main() {int size = sizeof(idt) / sizeof(idt[0]); // size = 256printf("%d\n",size);printf("%d %d\n", idt[0].a, idt[0].b);set_gate((unsigned long *)&idt[0]);printf("%d %d\n", idt[0].a, idt[0].b); // 输出 100 200return 0;
}
这个例子比较奇怪,奇怪在结构体的访问上。
main
函数调用了set_gate
函数,并且将idt[0]
的地址作为参数传了过去set_gate
函数获取了idt[0]
的地址之后,直接使用下标去访问结构体内的两个变量
我们知到,一般结构体变量是使用.
,结构体指针使用->
访问,这种使用下标的挺诡异的,我们分析一下。
- 结构体内的两个变量是连续的,都是
unsigned long
类型 - 现在有一个
unsigned long*
指针指向了结构体内第一个变量(默认指向开头)
我们可以看到,对于这种模式,不就是动态数组嘛,它们的形式是一样的,访问的时候,a和b可以通过指针的下标访问。
另外就是,由于获取的是指针,也就是地址,而且还不是结构体指针,而是与结构体内元素类型一致的指针,所以,也没有办法通过结构体的方式访问。
从底层来说,这种方式是可行的!需要明白,传参之后,结构体其实在函数set_gate
中是看不见的,是消失的。