C语言 可变数组


今天看Redis源代码,level是个可变数组。所有就深入的研究了C的可变数组问题。

  1. typedef struct changeable{  
  2.         int iCnt;  
  3.         char pc[0];  
  4. }schangeable;  
  5.   
  6. main(){  
  7.         printf("size of struct changeable : %d\n",sizeof(schangeable));  
  8.   
  9.         schangeable *pchangeable = (schangeable *)malloc(sizeof(schangeable) + 10*sizeof(char));  
  10.         printf("size of pchangeable : %d\n",sizeof(pchangeable));  
  11.   
  12.         schangeable *pchangeable2 = (schangeable *)malloc(sizeof(schangeable) + 20*sizeof(char));  
  13.         pchangeable2->iCnt = 20;  
  14.         printf("pchangeable2->iCnt : %d\n",pchangeable2->iCnt);  
  15.         strncpy(pchangeable2->pc,"hello world",11);  
  16.         printf("%s\n",pchangeable2->pc);  
  17.         printf("size of pchangeable2 : %d\n",sizeof(pchangeable2));  

运行结果

[cpp] view plain copy
  1. size of struct changeable : 4  
  2. size of pchangeable : 4  
  3. pchangeable2->iCnt : 20  
  4. hello world  
  5. size of pchangeable2 : 4  

结构体本身长度就是一个int长度(这个int值通常只为了表示后边的数组长度),后边的数组长度不计算在内,但是该数组可以直接使用。

(说后边是个指针吧?指针也占长度!这个是不占的!原理很简单,这个东西完全是数组后边的尾巴,malloc开辟的是一片连续空间。其实这不应该算一个机制,感觉应该更像一个技巧吧

这个机制利用了一个非常重要的特性——组和指针的区别!数组和指针在很多操作上是一样的,但是本质不一样。最直观的,指针可以改指向,数组不可以,因为数组占用的每一个内存地址都用来保存变量或者对象,而指针占用的内存地址保存的是一个地址,数组没有单独的保存指向地址的这样一个结构。数组的位置是固定的,正如指针变量自身的位置也是固定的,改的是指针的值,是指向的目标地址,而因为数组不存储目标地址,所以改不了指向。企图把地址强制赋值给数组的话,也只是说把指针赋值给数组,类型不兼容。

相关文章: