结构中零长度数组的目的是什么?

时间:2012-07-31 05:54:36

标签: c linux

当我查看Linux内核代码时,找到以下代码:

   struct thread_info {
    struct task_struct  *task;
    struct exec_domain  *exec_domain;
    unsigned long       flags;
    __u32           status;
    __u32           cpu;
    int         preempt_count;
    mm_segment_t        addr_limit;
    struct restart_block    restart_block;
    void __user     *sysenter_return;
    unsigned long           previous_esp;
    __u8            supervisor_stack[0];
};

注意最后一个变量“supervisor_stack”,它是一个零长度数组,它的用法是什么?提前谢谢!

2 个答案:

答案 0 :(得分:38)

这是灵活阵列成员的C99前版本,由GCC作为扩展提供。

C99的方法是用空括号定义灵活的数组成员

__u8  supervisor_stack[];

它用于存储数量与结构不连续的数据。内存以

的形式分配
struct foo *ptr = malloc(sizeof *ptr + whatever_is_needed);

在6.7.2.1的第18段中,标准(草案N1570)描述了它们:

  

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可以   有一个不完整的数组类型;这被称为灵活的阵列成员。在大多数情况下,   灵活的数组成员被忽略。特别是,结构的大小就像是   省略了灵活的数组成员,除了它可能有更多的尾随填充   遗漏意味着。但是,当.(或->)运算符具有左操作数时   (指向)具有灵活数组成员和右操作数名称的结构   成员,它的行为好像该成员被替换为最长的数组(具有相同的   元素类型)不会使结构大于被访问的对象;该   数组的偏移量应保持灵活阵列成员的偏移量,即使这会有所不同   从替换阵列的。如果此数组没有元素,则表现得好像   它有一个元素,但如果有任何尝试访问它,行为是未定义的   元素或生成一个经过它的指针。

答案 1 :(得分:10)

通常的C hack声明可以称为变量长度数组(在分配时定义大小的地方

示例:

struct line {
   int length;
   char contents[0];
 };

 struct line *thisline = (struct line *)
   malloc (sizeof (struct line) + this_length);
 thisline->length = this_length;

通过这种方式,您可以对数据进行结构定义,这也可以存储数组长度以实现明显的便利性,但您不会受到通常与结构相关联的固定大小的限制

取自here的示例(此处还有更多信息)