【发布时间】:2015-11-18 09:25:38
【问题描述】:
我试图说服(引用 C99 标准的特定部分)一位同事以下是未定义的行为:
int *p = malloc(1);
p[0] = 0;
但我在标准中找不到明确确保这是未定义的特定部分。 我正在专门寻找标准中从这些行得出结论的逻辑步骤:未定义的行为。是第一行从void * 到int * 的转换吗?第二行的赋值?
我能找到的关于 malloc 的唯一相关部分是它返回一个适当对齐的指针 (7.20.3):
如果分配成功,则返回的指针经过适当对齐,以便可以将其分配给指向任何类型对象的指针,然后用于访问分配的空间中的此类对象或此类对象的数组(...)
我尝试在规范中查找 space,但由于 white space 和其他词汇问题,噪音太大。
【问题讨论】:
-
您正在分配 1 字节的内存,然后写入
int(4 字节?)。这应该足以使它成为未定义的行为。 -
我编辑了问题以澄清我正在专门寻找标准中导致此结论的部分,因为虽然我知道它是 UB,但我无法在标准中找到适当的理由。
-
@Magisch "p[0] 等同于 p"——不,不是。 “并且指针在 c 中可以安全地自动正确使用”——不,它们不是,事实并非如此。
-
@Magisch "从功能上讲,它们是" - 不,它们不是。 如果
p是一个指针,那么p[0]与*p相同.您不可能断言指针始终与它指向的对象相同吗?另外,我没有说你需要投void *,因为你不需要。只是“指针在 c 中安全地自动正确使用”并不意味着, 因为指针在 C 中是不安全的。C 不是托管语言——而且“安全指针”与这种隐式类型转换无关。 -
@Magisch
p[i]表示*(p + i)。如果你想要p + i,则拼写为&p[i]。
标签: c malloc language-lawyer