文章链接:https://codemouse.online/archives/2020-02-24-164632
概念
【柔性数组结构成员:
C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员,但结构中的柔性数组成员前面必须至少一个其他成员。柔性数组成员允许结构中包含一个大小可变的数组。sizeof返回的这种结构大小不包括柔性数组的内存。包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。】
使用场景
- 在不知道数组长度的时候。
- 长度可以通过计算得到。
- 内存是提前分配好的。
实现
有时我们需要产生一个结构体,实现了一种可变长度的结构。如何来实现呢?
看这个结构体的定义:
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);