C說話的Struct Hack筆記。本站提示廣大學習愛好者:(C說話的Struct Hack筆記)文章只能為提供參考,不一定能成為您想要的結果。以下是C說話的Struct Hack筆記正文
比來在弄Compiler的CodeGenerator試驗,有一部門須要把Java法式翻譯成C法式,好比:
int [] array;
array = new int[10];
System.out.println(array.length); //10
這段代碼翻譯成C很天然的設法主意是:
int * array; // int array[] not support in C
array = (int*)malloc(sizof(int)*10);
printf("%d\n",sizof(array)/sizeof(int)); // 1
但很惋惜如許是毛病的,由於malloc操作在堆上分派空間,紛歧定是持續的,sizof(array)獲得的是指針自己所占的單位,和sizeof(int)相等,沒法經由過程sizof求得數組長度。它和上面還紛歧樣:
int array[10];
printf("%d\n",sizof(array)/sizeof(int)); // 10
這裡array是數組,是指向全部持續存儲空間的常量,所以sizeof對其操作求得的是全部區域的長度。然則當數組名作為函數的參數傳遞時,數組就退步為指針,又回到了適才成績。
我們應當怎樣做?
在 StackOverflow 搜了一下,發明ANSI C基本沒有直接手法經由過程指向內存的指針求得分派長度。但Windows下供給了盤算指針指向的內存年夜小的辦法[malloc.h]:
_msize : returns the size (in bytes) as an unsigned integer.
size_t _msize(
void *memblock
);
但因為操作體系戰略的緣由,現實分派到的年夜小能夠會比指定的年夜一些.
在Linux下,指針往前偏移一個整形年夜小的單位也會記載現實分派的年夜小,我們來窺測一下誰人單位的內容:
//test.c
int main(){
int * p;
int i;
int size;
for (i=1;i<11;i++)
printf("%d ",i);
printf("\n");
for (i=0;i<10;i++){
p = (int*)malloc(sizeof(int)*i);
size = *(int*)((char*)p-sizeof(int));
printf("size:%d ",size);
free(p);
}
printf("\n");
}
$gcc test.c
$./a.out
1 2 3 4 5 6 7 8 9 10
17 17 17 17 25 25 33 33 41 41
看來Linux的分派戰略不克不及使得內存年夜小和元素個數逐個對應,此法弗成用。 後來發明在Linux下本來也有相似_msize的函數[malloc.h]:
int * array;
int size;
array = (int*)malloc(sizof(50);
size = malloc_usable_size(array);
printf("%d\n",size);//50
然則malloc.h不屬於尺度C,我們還要持續尋覓通用之法。經由年夜量查閱,終究發明了一種code trick,稱作struct-hack. 後面提到過,在C說話中,int a[]是守法的,然則把它作為struct的最初一個成員倒是可以的:
typedef struct array{
int size;
int free;
int buf[];
}array,*Tiger_array;
這是在C說話的前期參加的特征,目標就是為了完成flexible array, 如許每次給數組分派空間時,須要同步記載size年夜小。而求size的時刻,直接掏出來便可:
Tiger_array ta;
ta = (int*)malloc(sizeof(array)+100);
ta->size = 100;
ta->free = 0;
須要留意一點,這時候分派的年夜小應當是sizeof(struct)加上需求的數組年夜小。
這個成績就說到這裡。