为结构的一部分分配内存

St.*_*rio 7 c struct undefined-behavior language-lawyer

我有以下示例

#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>

typedef struct test{
    int a;
    long b;
    int c;
} test;

int main()
{
    test *t = (test*) malloc(offsetof(test, c));
    t -> b = 100;
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我不确定.我想我在这里有UB.我们有一个指向结构类型对象的指针.但结构类型的对象并不真正有效.

我通过了标准,找不到这种行为的任何定义.我能找到的唯一一个接近这个的部分是6.5.3.2:

如果为指针分配了无效值,则unary*运算符的行为未定义

但这并不是真正相关的,因为返回的指针malloc是完全有效的.

标准中是否有参考解释这种行为?我正在使用C11 N1570.

Joh*_*ger 5

C2011开始,第6.2.6.1/4段:

存储在任何其他对象类型的非位字段对象中的值由nx个CHAR_BIT位组成,其中n是该类型对象的大小(以字节为单位).

因此,由于代码中的已分配对象小于a的大小struct test,因此它不能包含该类型对象的值.

现在考虑你的表达t -> b = 100. C2011,第6.5.2.3/4段定义了->运营商的行为:

后缀表达式后跟->运算符和标识符指定结构或联合对象的成员.该值是第一个表达式指向的对象的指定成员的值 [...].

(强调补充.)我们已经确定你的t(实际上,不能)指向a struct test,所以我们对6.5.2.3/4最好的说法是它不适用于你的情况.对于->运营商的行为没有其他定义,我们留下了第4/2段(增加了重点):

如果违反约束或运行时约束之外的''shall''或''shall not''要求,则行为未定义.未定义的行为在本国际标准中以"未定义的行为" 或"省略行为的任何明确定义"的方式表示.

你有.代码的行为未定义.