使用malloced内存未定义写入前读取?

根据这个reddit注释线程 ,如果在写入内存之前尝试读取内存,则它是未定义的。 我指的是正常的堆内存,它已成功地进行了malloc编辑。

…请注意,这不是严格有效的C:允许编译器/运行时系统使用所谓的陷阱表示来初始化未初始化的内存,这会导致访问时出现未定义的行为。

我觉得很难相信。 有标准报价吗?

当然,据我所知,无法保证内存已被清零。 这个未初始化的存储器中的值基本上是伪随机的或任意的。 但我真的不相信标准会将此称为未定义的行为 (从某种意义上说它可能是段错误,或者删除所有文件,或者其他什么)。 其余的reddit线程没有对此问题进行更多说明。

如果通过char*访问,则定义。 但除此之外,这是未定义的行为。

(C99,7.20.3.3)“malloc函数为一个对象分配空间,该对象的大小由大小指定,其值是不确定的。”

在不确定的价值:

(C99,3.17.2p1)“不确定值:未指定的值或陷阱表示”

在陷阱表示中通过非字符类型读取未定义的行为:

(C99,6.2.6.1p5)“某些对象表示不需要表示对象类型的值。如果对象的存储值具有这样的表示并且由不具有字符类型的左值表达式读取,则行为是未定义。[…]这种表示称为陷阱表示。“

它理性上必须是不确定的。 否则,在Valgrind之下运行的C程序的必要行为,在诊断读取未初始化的内存并在它们发生时抛出适当的错误,在标准下是非法的。

阅读标准,关键问题是malloc内存的值是“未指定值”(必须是一些可读值),还是“不确定值”(可能包含陷阱表示;参见定义3.17.2。)

根据7.20.3.3,在其他答案中引用,malloc返回一个包含不确定值的内存块,因此可能包含陷阱表示。 陷阱表示的相关讨论是6.2.6.1,第5部分:

某些对象表示不需要表示对象类型的值。 如果对象的存储值具有这样的表示,并且由不具有字符类型的左值表达式读取,则行为是未定义的。 ……这种表示称为陷阱表示

所以,你去吧。 基本上,C实现被允许检测(即“陷阱”)对不确定值的引用,并处理它选择的错误,包括以未定义的方式。

ISO / IEC 9899: 1999,7.20.3.3 mallocfunction:

malloc函数为一个对象分配空间,该对象的大小由size指定,其值是不确定的。

6.2.6.1类型的表示,§5:

某些对象表示不需要表示对象类型的值。 如果对象的存储值具有这样的表示,并且由不具有字符类型的左值表达式读取,则行为是未定义的。

脚注41使其更加明确(至少对于自动变量):

因此,可以将自动变量初始化为陷阱表示而不会导致未定义的行为,但是在其中存储适当的值之前,不能使用该变量的值。