![58276cca5a092ef20045b34a26ca31a1.png](https://img-blog.csdnimg.cn/img_convert/58276cca5a092ef20045b34a26ca31a1.png)
今天在学习linux服务器编程的时候遇到一个很奇怪的写法,大致就是子进程通过struct msghdr
这个结构体向父进程传递一个文件描述符,因为没有到msghdr
中的iovec*
类型的成员,作者直接就把一个零长度数组赋给iovec
中的iov_base
了......:
void send_fd(int fd, int fd_to_send)
{
struct iovec iov[1];
struct msghdr msg;
char buf[0];
iov[0].iov_base = buf;
//...
}
虽然到最后我也没明白为什么不赋NULL
给iov_base
,但是查了查资料发现零长度数组还是有其它用途的:方便缓冲内存管理。考虑下面两个结构体:
// length表示这个数据块长度,data指向数据块起始
struct data_block1
{
size_t length;
char data[0];
}
struct data_block2
{
size_t length;
char* data;
}
那么创建一个data_block2
变量,先要给这个变量分配一次内存
#define DATA_LEN 1024
struct data_block2* data = (struct data_block2*)malloc(sizeof(struct data_block2));
data->data = (char*)malloc(DATA_LEN);
然后再给data
这个成员分配块内存
#define DATA_LEN 1024
data->data = (char*)malloc(DATA_LEN);
但是data_block1
这个结构体可以一次干完上面两个事情
struct data_block1* data = (struct data_block1*)malloc(sizeof(struct data_block1) + DATA_LEN);
接着就可以用data
这个零长度数组来访问这块数据内存了
data->data[1] = '0';
这是因为malloc
一次分配的内存是连续的,因此可以用数组索引的方式来访问不属于data_block1
结构体的数据内存。在释放这块数据的时候也是只用free
一次就好了,而data_block2
则要free
两次。
这样的写法应该只有gcc编译器不会给你抛warning把。