堆栈上的结构 - 字段已初始化? [复制]

Posted

技术标签:

【中文标题】堆栈上的结构 - 字段已初始化? [复制]【英文标题】:structure on the stack - fields initialized? [duplicate] 【发布时间】:2018-04-06 17:57:27 【问题描述】:

考虑以下代码:

void func()

   int p;
   ...
   if (p > MAX) 
       struct my_struct s;
       ...
       /* here we access the contents 's' as '&s' */
   

在这个 sn-p 中,s 在堆栈上。是否保证编译器将所有结构字段初始化为零?

【问题讨论】:

绝对不是。 c中的自动存储没有进行自动初始化 【参考方案1】:

如果变量(struct 或其他)被声明为函数或包含范围的本地变量(即具有自动存储持续时间),则它不会以任何方式初始化。您需要明确设置struct 中的字段。

如果你初始化一个结构体的至少一个字段而不是全部,那么其余字段将被初始化为与文件范围变量(即具有静态存储持续时间的变量)相同,这意味着 NULL 用于指针类型,0 用于数字类型。

来自C standard 的第 6.7.9 节:

10 如果一个具有自动存储持续时间的对象没有被显式初始化,那么它的值是不确定的。 具有静态或线程存储持续时间未显式初始化, 那么:

——如果是指针类型,则初始化为空指针;

——如果它有算术类型,它被初始化为(正数或无符号数) 零;

——如果是聚合,每个成员都被初始化 (递归地)根据这些规则,并初始化任何填充 到零位;

——如果是联合,则第一个命名的成员是 根据这些规则初始化(递归),并且任何填充都是 初始化为零位;

...

21 如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员数,或 用于初始化已知大小的数组的字符串文字 是数组中的元素,聚合的其余部分应为 隐式初始化与具有静态存储的对象相同 持续时间。

【讨论】:

"如果你至少初始化了一个结构体的一个字段而不是全部,那么剩余的字段将被初始化为 0。" -- 这是由 C 标准保证的吗? @Mark 0 或同等学历,但大多数情况下,是的, @Mark 是的。查看我的编辑。【参考方案2】:

不,恰恰相反。

由于s 是一个自动存储本地范围(即块范围)变量,除非显式初始化,否则内容是不确定

引用C11,第 6.7.9 章

如果具有自动存储持续时间的对象未显式初始化,则其值为 不定。 [...]。

但是,如果您想对一个(y)聚合类型的变量进行零初始化,您可以简单地使用初始化语句,如

aggregate-type variable = 0;

它使用同一章第 21 段中的以下属性,(强调我的

如果大括号括起来的列表中的初始值设定项少于元素或成员的数量 聚合,或用于初始化已知数组的字符串文字中的更少字符 大小超过数组中的元素,聚合的其余部分应为 隐式初始化与具有静态存储持续时间的对象相同。

【讨论】:

【参考方案3】:

不,它们根本不会被初始化。结构值最终会与放置结构的堆栈上的任何垃圾一起结束。

【讨论】:

【参考方案4】:
struct my_struct s;
       ...
       /* here we access the contents 's' as '&s' */

这里你没有静态变量,你有一个自动变量,所以没有预初始化。

另一方面,如果您使用优化进行编译,则无法保证编译器将这个变量存储在哪里,除非您检查汇编器的输出,这不是由 C 语言定义的。

【讨论】:

以上是关于堆栈上的结构 - 字段已初始化? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

初始化复杂结构,GCC 警告:已覆盖副作用的初始化字段

将初始值设置为 c 中结构的字段? [复制]

何时使指针指向堆上的结构与堆栈上的结构? [复制]

C结构初始化? [复制]

进程空间分配和堆栈大小

静态区堆栈