结构体中最后成员为一个数组(长度为零)与一个指针

转自:http://blog.csdn.net/cylan_jia/article/details/7753465

1. 结构体中最后一个数组长度为零

 
 
 
 
[plain] view plain copy
  1. typedef struct _ex_mng  
  2. {  
  3.     unsigned int type;  
  4.     unsigned int oper;  
  5.     char data[0];  
  6. }ex_mng_t;  
    最近在项目常用到这样子的一个结构体,最后一个成员为可变长的数组。
    char data[0]中的data并不是指针,是一个偏移量,这个偏移量指向的是a、b后面紧接着的空间,代表了该结构体后面数据的起始地址,所以它其实并不占用任何空间,因此sizeofstruct  _ex_mng) = 8   使用起来非常方便,创建时,malloc一段结构体大小加上可变长数据长度的空间给它,可变长部分可按数组的方式访问,释放时,直接把整个结构体free掉就可以了。

例子: 

[plain] view plain copy
  1. ex_mng_t *ex_mng;  
  2. int datalen = 100;  
  3. /* 申请内存(结构体以及data的内存)*/     
  4. ex_mng = (ex_mng_t *)malloc(sizeof(ex_mng_t) + datalen );     
  5. ex_mng->type = 1;     
  6. ex_mng->oper = 1;     
  7. strcpy(ex_mng->data, "success!");  

    在结构体中,我们定义了0长度的数组,按理对ex_mng->data进行赋值时是属于越界访问,但是我们把结构体后面的datalen个长度的空间也一起申请了,所以该访问是合法的! 

2. 结构体中最后一个成员为指针

 
 
[plain] view plain copy
  1. typedef struct _ex_mng  
  2. {  
  3.     unsigned int type;  
  4.     unsigned int oper;  
  5.     char *data;  
  6. }ex_mng_t;  
而如果是指针的话,使用时候需要初始化,并且占用空间, sizeof struct _ex_mng)  = 12 32 位) /sizeof struct _ex_mng)  = 12 64 位)。
使用方法一:  
[plain] view plain copy
  1. ex_mng_t *ex_mng;  
  2. int datalen = 100;  
  3. /* 申请内存(结构体) */  
  4. ex_mng = (ex_mng_t *)malloc(sizeof(ex_mng_t));  
  5. ex_mng->type = 1;  
  6. ex_mng->oper = 1;  
  7. /* 申请内存(data) */  
  8. ex_mng->data = malloc(sizeof(char)* datalen );  
  9. strcpy(ex_mng->data, "success!");  
  10. /* 释放内存(data)*/  
  11. free(ex_mng->data);  
  12. /* 释放内存(结构体)*/  
  13. free(ex_mng);  

使用方法二:
[plain] view plain copy
  1. ex_mng_t *ex_mng;  
  2. int datalen = 100;  
  3. /* 申请内存(结构体+data) */  
  4. ex_mng = (ex_mng_t *)malloc(sizeof(ex_mng_t) + sizeof(char)*datalen);  
  5. ex_mng->type = 1;  
  6. ex_mng->oper = 1;  
  7. /* ex_mng->data指向结构体后的内存 */  
  8. ex_mng->data = ((char *)ex_mng ) + sizeof(ex_mng_t);  
  9. strcpy(ex_mng->data, "success!");  
  10. /* 释放内存(结构体+data)*/  
  11. free(ex_mng);  

注意:结构体中最后一个数组长度为零,有些编译器会报错无法编译,可以改成char data[1], 或则 char data[] 总之,结构体最后使用 0 1 的长度数组的原因,主要是为了方便的管理内存缓冲区,当使用指针时候(使用方法一时),不能分配一段连续的的内存,会增加内存的碎片化。

猜你喜欢

转载自blog.csdn.net/zzwdkxx/article/details/79026340