今天看Redis源代码,level是个可变数组。所有就深入的研究了C的可变数组问题。
- typedef struct changeable{
- int iCnt;
- char pc[0];
- }schangeable;
- main(){
- printf("size of struct changeable : %d\n",sizeof(schangeable));
- schangeable *pchangeable = (schangeable *)malloc(sizeof(schangeable) + 10*sizeof(char));
- printf("size of pchangeable : %d\n",sizeof(pchangeable));
- schangeable *pchangeable2 = (schangeable *)malloc(sizeof(schangeable) + 20*sizeof(char));
- pchangeable2->iCnt = 20;
- printf("pchangeable2->iCnt : %d\n",pchangeable2->iCnt);
- strncpy(pchangeable2->pc,"hello world",11);
- printf("%s\n",pchangeable2->pc);
- printf("size of pchangeable2 : %d\n",sizeof(pchangeable2));
运行结果
- size of struct changeable : 4
- size of pchangeable : 4
- pchangeable2->iCnt : 20
- hello world
- size of pchangeable2 : 4
结构体本身长度就是一个int长度(这个int值通常只为了表示后边的数组长度),后边的数组长度不计算在内,但是该数组可以直接使用。
(说后边是个指针吧?指针也占长度!这个是不占的!原理很简单,这个东西完全是数组后边的尾巴,malloc开辟的是一片连续空间。其实这不应该算一个机制,感觉应该更像一个技巧吧)
这个机制利用了一个非常重要的特性——数组和指针的区别!数组和指针在很多操作上是一样的,但是本质不一样。最直观的,指针可以改指向,数组不可以,因为数组占用的每一个内存地址都用来保存变量或者对象,而指针占用的内存地址保存的是一个地址,数组没有单独的保存指向地址的这样一个结构。数组的位置是固定的,正如指针变量自身的位置也是固定的,改的是指针的值,是指向的目标地址,而因为数组不存储目标地址,所以改不了指向。企图把地址强制赋值给数组的话,也只是说把指针赋值给数组,类型不兼容。