나는 그것을 알아 차렸다 struct pid
.
pid.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
이는 주어진 수준에서 에 충분한 공간을 할당합니다(0부터 시작하므로 하나에 공간을 할당합니다 struct upid
).
struct pid
numbers
배열의 요소를 위한 공간 자체가 있습니다 .레벨 0 캐시 할당 및 사용KMEM_CACHE
, 그리고 기대한다완전한 캐시 항목을 나타내는 단일 구조.
지난 몇 년 동안 이러한 모든 어레이 사용을 표준화된 유연한 어레이로 전환하는 데 전념해 왔습니다. 자세한 내용은 다음을 참조하세요.커널 자체 보호 프로젝트에 대한 Gustavo AR Silva의 최근 강연2022 커널 레시피.