零长度数组创建可变结构体

在阅读代码的时候发现,发现有的结构体末尾为附加一个0长度或者1长度的数组。其实这是一个小技巧,用这种方法可以实现变长结构体。变长结构体通常在网络通信中的报文头中比较常见。

struct Extra
{
	int m_ext;
};
struct Header
{
	int m_data;
	int m_size;
	char extra[0];
};

如上所示,struct Header的最后一个字段是长度为零的char类型数组。这个数组有什么用呢?实际上它被用来表示一个地址,这个地址指向Header结构体的末尾。有了这个指向结构体末尾的地址,我们就可以在这个地址上紧接着Header结构体放一些不定长度的附加信息。像下面的例子一样:

int alloc_size = sizeof(struct Header) + sizeof(struct Extra) * 5;

struct Header* pHeader = (struct Header*)malloc(alloc_size);
pHeader->m_data = 1;
pHeader->m_size = alloc_size;

//紧接着结构体放置附加字段,此处附加字段为5个struct Extra
struct Extra* pExtra = (struct Extra*)(pHeader->extra);
for (int i = 0; i < 5; ++i)
{
    struct Extra* pCurrExtra = pExtra + i;
    pCurrExtra->m_ext = i + 1;
}

 由于有的编译器不支持0长度数组,所以这种情况下也可以用1长度数组:char extra[1],只不过这样整个Header结构体增加了1字节大小(不考虑内存对齐)。这个数组的类型也不一定非得是char,在我们的例子中,也可以是struct Extra[0]。

当时非常纳闷的一点是,数组的长度只有0或者1,那我们访问的时候不会溢出吗?其实溢出或者不溢出不在于数组的长度,而在于我们的指针所访问的地址是否是合法地址,比如我们的例子中pExtra + 2并不会溢出,因为pExtra+2所指的地址是我们自己分配的合法地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值