可变数组/柔性数组/0长度数组

GNU/GCC 在标准 C/C++ 基础上做了有实用性的扩展, 零长度数组(Arrays of Length Zero) 就是其中一个知名的扩展。在一个结构体的最后, 申明一个长度为0的数组, 就可以使得这个结构体是可变长的。这种结构体要求:第一,0长度数组放在最后,第二,成员不能只有0长度数组,至少还应该有其他成员。比起在结构体中声明一个指针变量、再进行动态分 配的办法,这种方法效率要高。因为在访问数组内容时,不需要间接访问,避免了两次访存。

sizeof这个结构体类型时,0长度数组不算字节;开辟空间(malloc)时,根据实际需求开辟数组空间。

优点:比起在结构体中声明一个指针变量、再进行动态分 配的办法,这种方法效率要高。因为在访问数组内容时,不需要间接访问,避免了两次访存。

struct Packet
{
    int state;
    int len;
    char cData[0]; //这里的0长结构体就为变长结构体提供了非常好的支持
};

举例:设想一个场景, 我们在网络通信过程中使用的数据缓冲区, 缓冲区包括一个len字段和data字段, 分别标识数据的长度和传输的数据, 我们常见的有几种设计思路:第一,定长数据缓冲区, 设置一个足够大小 MAX_LENGTH 的数据缓冲区;第二,设置一个指向实际数据的指针, 每次使用时, 按照数据的长度动态的开辟数据缓冲区的空间;第三,使用可变数组。

第一:

// 定长缓冲区
struct max_buffer
{
    int     len;
    char    data[MAX_LENGTH];
};

///  开辟
if ((mbuffer = (struct max_buffer *)malloc(sizeof(struct max_buffer))) != NULL)
{
    mbuffer->len = CURR_LENGTH;
    memcpy(mbuffer->data, "Hello World", CURR_LENGTH);
    printf("%d, %s\n", mbuffer->len, mbuffer->data);
}
/// 销毁
free(mbuffer);
mbuffer = NULL;

第二:

//指针
struct point_buffer
{
    int     len;
    char    *data;
};

//  开辟
if ((pbuffer = (struct point_buffer *)malloc(sizeof(struct point_buffer))) != NULL){
    pbuffer->len = CURR_LENGTH;
    if ((pbuffer->data = (char *)malloc(sizeof(char) * CURR_LENGTH)) != NULL)
    {
        memcpy(pbuffer->data, "Hello World", CURR_LENGTH);
        printf("%d, %s\n", pbuffer->len, pbuffer->data);
    }
}

// 销毁
free(pbuffer->data);
free(pbuffer);
pbuffer = NULL;

第三:

// 0长度数组
struct zero_buffer
{
    int     len;
    char    data[0];
};

// 开辟
if ((zbuffer = (struct zero_buffer *)malloc(sizeof(struct zero_buffer) + sizeof(char) * CURR_LENGTH)) != NULL)
{
    zbuffer->len = CURR_LENGTH;
    memcpy(zbuffer->data, "Hello World", CURR_LENGTH);
    printf("%d, %s\n", zbuffer->len, zbuffer->data);
}

// 销毁
free(zbuffer);
zbuffer = NULL;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值