很久没有使用C语言的变长数组,基本特性有点模糊,加强一个记忆。
释义
struct MyData{
int len;
char data[0];
}
在这个结构中,data是一个数组名;但该数组没有元素;该数组的真实地址紧随结构体MyData之后,而这个地址就是结构体后面数据的地址(如果给这个结构体分配的内容大于这个结构体实际大小,后面多余的部分就是这个data的内容);这种声明方法可以巧妙的实现C语言里的数组扩展。
其中,系统并不会给data[0]分配内存,即 sizeof(int) == sizeof(struct MyData)。
常用方式
struct MyData{
int len;
char data[0];
};
char str[10] = "0123456789";
struct MyData *mydataptr = (struct MyData *)malloc(sizeof(struct MyData) + 10);
memcpy(mydataptr->data, str, strlen(str));
free(mydataptr);
即可以在分配内存时, 分配变长的空间。
注意事项
字节对齐的问题!
struct MyData{
int len;
char ch;
char data[0];
};
GCC默认4字节对齐,将会导致data[0]的地址并非你所想要的位置。
故而需要完善为:
struct MyData{
int len;
char ch;
char data[0];
}__attribute ((packed));
测试程序
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 int main(){
6 struct MyData{
7 int len;
8 char data[0];
9 }__attribute ((packed));
10
11 char str[10] = "0123456789";
12 struct MyData *mydataptr = (struct MyData *)malloc(sizeof(struct MyData) + 10);
13
14 memcpy(mydataptr->data, str, strlen(str));
15 mydataptr->len = 99;
16
17 printf("sizeof(int) = %d\n", sizeof(int));
18 printf("sizeof(MyData) = %d\n", sizeof(struct MyData));
19
20 for(int i = 0; i < (sizeof(struct MyData) + 10); i++){
21 printf("%c ", *(((char *)mydataptr + i)));
22 }
23 printf("\n");
24
25 free(mydataptr);
26 return 0;
27 }
运行结果: