国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C > 正文

C語(yǔ)言的Struct Hack筆記

2020-01-26 15:32:06
字體:
供稿:網(wǎng)友

最近在搞Compiler的CodeGenerator實(shí)驗(yàn),有一部分需要把Java程序翻譯成C程序,比如:

復(fù)制代碼 代碼如下:

int [] array;
array = new int[10];
System.out.println(array.length); //10

這段代碼翻譯成C很自然的想法是:
復(fù)制代碼 代碼如下:

int * array; // int array[] not support in C
array = (int*)malloc(sizof(int)*10);
printf("%d/n",sizof(array)/sizeof(int)); // 1

但很可惜這樣是錯(cuò)誤的,因?yàn)閙alloc操作在堆上分配空間,不一定是連續(xù)的,sizof(array)得到的是指針本身所占的單元,和sizeof(int)相等,無法通過sizof求得數(shù)組長(zhǎng)度。它和下面還不一樣:
復(fù)制代碼 代碼如下:

int array[10];
printf("%d/n",sizof(array)/sizeof(int)); // 10

這里array是數(shù)組,是指向整個(gè)連續(xù)存儲(chǔ)空間的常量,所以sizeof對(duì)其操作求得的是整個(gè)區(qū)域的長(zhǎng)度。但是當(dāng)數(shù)組名作為函數(shù)的參數(shù)傳遞時(shí),數(shù)組就退化為指針,又回到了剛才問題。

我們應(yīng)該怎么做?

在 StackOverflow 搜了一下,發(fā)現(xiàn)ANSI C根本沒有直接辦法通過指向內(nèi)存的指針求得分配長(zhǎng)度。但Windows下提供了計(jì)算指針指向的內(nèi)存大小的方法[malloc.h]:

_msize : returns the size (in bytes) as an unsigned integer.

復(fù)制代碼 代碼如下:

size_t _msize(
void *memblock
);


但由于操作系統(tǒng)策略的原因,實(shí)際分配到的大小可能會(huì)比指定的大一些.

在Linux下,指針往前偏移一個(gè)整形大小的單元也會(huì)記錄實(shí)際分配的大小,我們來窺探一下那個(gè)單元的內(nèi)容:

復(fù)制代碼 代碼如下:

//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的分配策略不能使得內(nèi)存大小和元素個(gè)數(shù)一一對(duì)應(yīng),此法不可用。 后來發(fā)現(xiàn)在Linux下原來也有類似_msize的函數(shù)[malloc.h]:

復(fù)制代碼 代碼如下:

int * array;
int size;
array = (int*)malloc(sizof(50);
size = malloc_usable_size(array);
printf("%d/n",size);//50

但是malloc.h不屬于標(biāo)準(zhǔn)C,我們還要繼續(xù)尋找通用之法。經(jīng)過大量查閱,終于發(fā)現(xiàn)了一種code trick,稱作struct-hack. 前面提到過,在C語(yǔ)言中,int a[]是違法的,但是把它作為struct的最后一個(gè)成員卻是可以的:

復(fù)制代碼 代碼如下:

typedef struct array{
 int size;
 int free;
 int buf[];
 }array,*Tiger_array;


這是在C語(yǔ)言的后期加入的特性,目的就是為了實(shí)現(xiàn)flexible array, 這樣每次給數(shù)組分配空間時(shí),需要同步記錄size大小。而求size的時(shí)候,直接取出來即可:

復(fù)制代碼 代碼如下:

 Tiger_array ta;
ta = (int*)malloc(sizeof(array)+100);
ta->size = 100;
ta->free = 0;

需要注意一點(diǎn),這時(shí)分配的大小應(yīng)該是sizeof(struct)加上需求的數(shù)組大小。

這個(gè)問題就說到這里。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 青海省| 河源市| 铁力市| 寻乌县| 庆云县| 牡丹江市| 彩票| 虎林市| 宁城县| 盈江县| 遂川县| 鄂州市| 三亚市| 朝阳市| 云霄县| 闸北区| 乌兰浩特市| 且末县| 拜城县| 密云县| 石嘴山市| 邢台县| 南岸区| 巢湖市| 曲麻莱县| 镇雄县| 盱眙县| 英德市| 饶河县| 旺苍县| 屯门区| 元阳县| 手机| 礼泉县| 蒲江县| 合作市| 嵊州市| 岳池县| 隆化县| 正定县| 通榆县|