为什么“struct pid”成员“numbers”定义为大小为1的数组?

为什么“struct pid”成员“numbers”定义为大小为1的数组?

我注意到,struct pidpid.h,该成员numbers被定义为大小为 1 的数组。

struct pid
{
    refcount_t count;
    unsigned int level;
    spinlock_t lock;
    /* lists of tasks that use this pid */
    struct hlist_head tasks[PIDTYPE_MAX];
    struct hlist_head inodes;
    /* wait queue for pidfd notifications */
    wait_queue_head_t wait_pidfd;
    struct rcu_head rcu;
    struct upid numbers[1];
};

然而,在pid.c,使用 0 以外的索引访问该成员。

pid->numbers[i].nr = nr;

这是如何在不越界的情况下工作的?

答案1

这是灵活数组的一个变体,尽管没有使用现在的标准语法(应该是struct upid numbers[];)。一般的想法是,为此类结构体分配足够的空间用于所有字段,并为结构体末尾的数组的实际大小分配足够的空间。

这些结构被分配在缓存中;你可以看到尺寸计算create_pid_cachep

len = sizeof(struct pid) + level * sizeof(struct upid);

struct pid这会在给定级别为 a 分配足够的空间(从 0 开始,因此为 one 分配空间struct upid)。

struct pid其本身有空间容纳其numbers数组中的一个元素,因为0级缓存的分配使用KMEM_CACHE,并且期望代表完整缓存条目的单个结构

过去几年一直致力于将所有此类阵列用途转换为标准化的灵活阵列;有关更多信息,请参阅Gustavo AR Silva 最近关于内核自我保护项目的演讲2022 年内核食谱。

相关内容