最近我遇到了一个结构定义,
struct arr {
int cnt;
struct {
int size;
int *name;
} list[0];
};
Run Code Online (Sandbox Code Playgroud)
现在我不知道list[0]被宣布的原因.我感兴趣的是为什么使用它.它有什么优势吗?如果是,那是什么?
unw*_*ind 18
用于动态长度数组.您可以使用分配内存malloc(),并将数组驻留在结构的末尾:
struct arr *my_arr = malloc(sizeof *my_arr + 17 * sizeof *my_arr->list);
my_arr->cnt = 17;
my_arr->list[0].size = 0;
my_arr->list[1].name = "foo";
Run Code Online (Sandbox Code Playgroud)
实际上能够使用0作为长度是(如评论中所指出的)GCC扩展.在C99中,您可以完全忽略大小文字以获得相同的效果.
在实现这些事情之前,您经常看到这个完成时长度为1,但这会使分配复杂化,因为在计算所需内存时必须进行补偿.
AnT*_*AnT 11
它被称为"struct hack".您可以在SO或网上搜索它
http://www.google.com/search?q=struct+hack&sitesearch=stackoverflow.com/questions
请注意,正式声明在C中声明大小为0的数组总是违法的.您正式提供的代码甚至无法编译.大多数C编译器都接受0大小的数组声明作为扩展,特别是因为它经常用于"结构黑客"的"懒惰"版本(它可以依赖于sizeof确定要分配多少内存,因为0大小的数组应该是不影响结构的总大小).
可以说更好的struct hack实现使用大小为1的数组
struct arr {
int cnt;
struct {
int size;
int *name;
} list[1];
};
Run Code Online (Sandbox Code Playgroud)
它"更好",因为它至少可以正式编译.为了为包含N元素的结构分配内存list,使用标准offsetof宏
arr *a = malloc(offsetof(arr, list) + N * sizeof a->list);
Run Code Online (Sandbox Code Playgroud)
在C99版本的语言规范中,通过无大小数组声明(带空[])支持"struct hack" ,因为0大小的数组声明在C99中也是非法的.