代码之家  ›  专栏  ›  技术社区  ›  St.Antario

为结构的一部分分配内存

  •  7
  • St.Antario  · 技术社区  · 6 年前

    我有下面的例子

    #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;
    }
    

    它很好用,但我不确定。我想我这里有UB。我们有一个指向结构类型对象的指针。但是结构类型的对象不是真正有效的。

    我检查了标准,找不到这种行为的任何定义。我能找到的唯一接近这一部分是6.5.3.2:

    如果为指针指定了无效值,则 一元*运算符未定义

    malloc

    标准中是否有解释此类行为的参考?我用的是C11 N1570。

    2 回复  |  直到 6 年前
        1
  •  6
  •   John Bollinger    6 年前

    从…起 C2011, paragraph 6.2.6.1/4 :

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

    struct test ,它不能包含该类型对象的值。

    现在考虑你的表达 t -> b = 100 . C2011, paragraph 6.5.2.3/4 定义对象的行为 -> 接线员:

    后跟 -&燃气轮机; 运算符和标识符指定结构或联合对象的成员。该值是命名成员的值 第一个表达式指向的对象的

    (重点补充)我们已经确定 t 不(确实),, 不能 )指向 结构测试 ,但是,关于6.5.2.3/4,我们只能说它不适用于您的情况。没有其他定义的行为 -&燃气轮机; 接线员,我们只剩下 paragraph 4/2

    如果违反了出现在约束或运行时约束之外的“应”或“不应”要求,则行为未定义。未定义的行为在本国际标准中用“未定义的行为”一词表示 或者忽略任何明确的行为定义

    原来你在这里。代码的行为未定义。

        2
  •  -2
  •   Andrew Henle    6 年前

    因为malloc返回的指针是完全有效的。

    否指针不是“完全有效”。一点也不。

    为什么你认为指针是“完全有效的”?您没有分配足够的字节来保存整个文件 struct test -指针不是“完全有效”,因为没有有效的 结构测试 对象以供您访问。

    在C中没有分部对象,这就是为什么在C标准中找不到分部对象的原因。

    它很好用

    不,没有。

    “我没注意到它爆炸了。”这和“它工作正常”不一样

    你的代码没有做任何可以观察到的事情。每 the as-if rule main() .