首页 > 其他 > 详细

变长结构体

时间:2014-04-11 08:58:54      阅读:404      评论:0      收藏:0      [点我收藏+]

变长结构体

 

变长结构体是由gcc扩展的一种技术,它是指其最后一个成员的长度不固定flexible array member,也叫柔性数组,先来看一个简单的例子:

bubuko.com,布布扣
#include <stdlib.h>
#include <stdio.h>

#pragma pack(1)
typedef struct {
    int a;
    char b[10];
    char *vector;         
} cq; 
#pragma pack()

int main()
{
    cq *a = malloc(sizeof(cq));

    char str[] = "hello";

    a->vector = malloc(sizeof(str));
    memcpy(a->vector, str, sizeof(str));

    printf("%s\n", a->vector);       // "hello"
    printf("%d\n", sizeof(cq));      // 22

    free(a->vector);
    free(a);

    return 0;
}
bubuko.com,布布扣

这段代码中,结构体cq中的成员vector是一个指针,你在分配内存缓冲区时,就必须分配结构体一次,然后再分配结构体内的指针一次,(而此时分配的内存已经与结构体的内存不连续了,所以要分别管理即申请和释放)。

而如果使用数组,那么只需要一次就可以全部分配出来,(见下面的例子),反过来,释放时也是一样,一次释放。而使用指针,得先释放结构体内的指针,再释放结构体。还不能颠倒次序。其次,就是分配一段连续的的内存,减少内存的碎片化。

 

bubuko.com,布布扣
#include <stdlib.h>
#include <stdio.h>

#pragma pack(1)
typedef struct {
    int a;
    char b[10];
    char vector[0];         // 可变数组
} cq; 
#pragma pack()

int main()
{
    char str[] = "hello";

    cq *a = malloc(sizeof(cq) + sizeof(str));   // decide amount used
    memcpy(a->vector, str, sizeof(str));

    printf("%s\n", a->vector);       // "hello"
    printf("%d\n", sizeof(cq));      // 14

    free(a);

    return 0;
}
bubuko.com,布布扣

例子中,打印出的结构体长度是14(为成员a和b的长度之和),——变长数组vector不占结构体的空间!

可见,变长结构体是能让我们在分配时再决定其大小,而不是在定义时就要固定其数组长度。

 

可变数组的一种更通用的用法是用一个成员指明变长数组的长度,方便在其他地方读取数组内容。

bubuko.com,布布扣
struct line {
   int length;
   char contents[0];
};

struct line *thisline = (struct line *)malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
bubuko.com,布布扣

 

 

最后,转述一段C99标准(draft N1570)对这个问题的描述,本人英文很烂,就不翻译了。

As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a ?exible array member. In most situations, the ?exible array member is ignored. In particular, the size of the structure is as if the ?exible array member were omitted except that it may have more trailing padding than the omission would imply. However, when a . (or ->) operator has a left operand that is (a pointer to) a structure with a ?exible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed; the offset of the array shall remain that of the ?exible array member, even if this would differ from that of the replacement array. If this array would have no elements, it behaves as if it had one element but the behavior is unde?ned if any attempt is made to access that element or to generate a pointer one past it.

 

参考:

http://stackoverflow.com/questions/11733981/what-is-the-purpose-of-a-zero-length-array-in-a-struct

 

 

 

 

 

 

 

变长结构体,布布扣,bubuko.com

变长结构体

原文:http://www.cnblogs.com/chenny7/p/3657712.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!