在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
中是看不見的,是消失的。