c - 数组中的元素数量是否可能超过编译时定义的数组大小?

标签 c arrays linux struct linux-kernel

<分区>

在 linux 内核(版本 4.8)中, “struct pid”定义如下(来自文件:http://lxr.free-electrons.com/source/include/linux/pid.h)。这里的“numbers[1]”(在第 64 行)是一个静态数组,它只能有一个元素(因为数组大小被称为 1)。

 57 struct pid
 58 {
 59         atomic_t count;
 60         unsigned int level;
 61         /* lists of tasks that use this pid */
 62         struct hlist_head tasks[PIDTYPE_MAX];
 63         struct rcu_head rcu;
 64         struct upid numbers[1];
 65 };

但是,在下面第 319 行和第 320 行的代码中(来自文件:http://lxr.free-electrons.com/source/kernel/pid.c),数组“numbers”作为“numbers[i]”在 for 循环中。它是如何正确的,因为变量“i”不能有除零以外的任何值而不会导致段错误?我已经在循环期间检查了“i”的值,看它是否超过 1。是的,但我仍然没有看到任何段错误。我在这里错过了什么吗?

297 struct pid *alloc_pid(struct pid_namespace *ns)
298 {
299         struct pid *pid;
300         enum pid_type type;
301         int i, nr;
302         struct pid_namespace *tmp;
303         struct upid *upid;
304         int retval = -ENOMEM;
305 
306         pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
307         if (!pid)
308                 return ERR_PTR(retval);
309 
310         tmp = ns;
311         pid->level = ns->level;
312         for (i = ns->level; i >= 0; i--) {
313                 nr = alloc_pidmap(tmp);
314                 if (nr < 0) {
315                         retval = nr;
316                         goto out_free;
317                 }
318 
319                 pid->numbers[i].nr = nr;
320                 pid->numbers[i].ns = tmp;
321                 tmp = tmp->parent;
322         }

最佳答案

Is it possible to have number of elements in an array more than array's size which is defined at compile time?

是的。这是调用未定义的行为,不应编写代码来允许这种情况。

How is it even correct because variable 'i' cannot have any value other than zero without causing segmentation fault?

这是可能的;因为代码违反了契约(Contract)。在数组边界之外写入可能 有效。它可能会使程序崩溃。这是未定义的行为


C 未指定防止超出其边界的数组访问,也不会导致段错误。这样的访问可能会被捕获,也可能不会。代码本身需要负责确保访问在范围内。
没有 training wheels很少safety nets在 C 中指定

关于c - 数组中的元素数量是否可能超过编译时定义的数组大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41081673/

相关文章:

javascript - 使用复选框过滤器创建/删除 div

javascript:在数组中查找重叠的圆圈

java - 数组舍入

linux - 使用 OpenSSL 哈希进行文件比较

linux - Fedora 14 - 错误 5 - 磁盘上没有空间 - 安装后

c - C : How to properly call function inside main 中的问题

javascript - 在网络浏览器上显示保存的文件

c - sprintf() 是否需要格式说明符才能正常工作?

c - MISRA-2012 违反规则 20.12 : misra_c_2012_rule_20_12_violation: macro parameter "val" is used in both expanded and raw forms

c++ - Boost、bjam 和符号链接(symbolic link)