柔性数组

大耗子 2020年02月24日 187次浏览

文章链接:https://codemouse.online/archives/2020-02-24-164632

概念

【柔性数组结构成员:
  C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员,但结构中的柔性数组成员前面必须至少一个其他成员。柔性数组成员允许结构中包含一个大小可变的数组。sizeof返回的这种结构大小不包括柔性数组的内存。包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。】

使用场景

  1. 在不知道数组长度的时候。
  2. 长度可以通过计算得到。
  3. 内存是提前分配好的。

实现

有时我们需要产生一个结构体,实现了一种可变长度的结构。如何来实现呢?
看这个结构体的定义:

typedef struct st_type
{
    int nCnt;
    int item[0];
}type_a;
(有些编译器会报错无法编译可以改成:)
typedef struct st_type
{
    int nCnt;
    int item[];
}type_a;

这样我们就可以定义一个可变长的结构,用sizeof(type_a)得到的只有4,就是sizeof(nCnt)=sizeof(int)那个0个元素的数组没有占用空间,而后我们可以进行变长操作了。

申请

C语言版:

type_a *p = (type_a *)malloc(sizeof(type_a) + 100*sizeof(int));

C++ 语言版:

type_a *p = (type_a *)new char[sizeof(type_a) + 100*sizeof(int)];

这样我们就产生了一个长为100的type_a类型的东西用p->item[n]就能简单地访问可变长元素.

释放

C语言版:

free(p);

C++ 语言版:

delete []p;

好处

typedef struct{
    char a[1];
    char b[];
}AA;
AA *pf;
pf = malloc(sizeof(AA) + 5*sizeof(char));/*只分配一块内存*/

如果这样定义

typedef struct{
    char a[1];
    char *b;
}AA;
AA *pf;
pf = malloc(sizeof(AA));
pf->b = malloc(5*sizeof(char));
/*看出来了么,这样需要分配两块内存,在释放时也要先释放b的内存,再释放pf的内存*/

减少了内存的释放,同时对于还满足了变长结构体的需求

也可以如下使用变长结构体,(通常在做协议发送的时候使用)

typedef struct{
    char length;
    char name[1];
}DATA1;
typedef struct{
    char length;
    char passwd[1];
}DATA2;

char arr[1024] = {0};
DATA1 * p1 = arr;
memcpy(p1->name,"name",p1->length);
DATA2 * p2 = arr+p1->length+1;
memcpy(p2->passwd,"passwd",p2->length);
write(sockfd, arr, p1->length+p2->length+2);