我们可以重用已分配的内存

时间:2018-02-01 11:23:20

标签: c memory-management malloc language-lawyer

这是this question的后续行动。

在解释我的问题时,我声明分配的内存可以重用,因为它没有声明的类型,我被告知它是不正确的C.

以下是一个说明问题的代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

struct Elt {
    int id;
    char name[32];
};

struct Elt2 {
    double val;
    char name[16];
};

static_assert(sizeof(struct Elt2) < sizeof(struct Elt), "Incorrect sizes");

int main() {
    struct Elt actual1 = { 1, "foo"};
    struct Elt2 actual2 = {2.0, "bar"};

    struct Elt* elt = malloc(sizeof(struct Elt));
    memcpy(elt, &actual1, sizeof(*elt));          // populates the allocated memory
    printf("elt: %d %s\n", elt->id, elt->name);
    struct Elt2 *elt2 = (void *) elt;             // declares a new pointer to a shorter type
    memcpy(elt2, &actual2, sizeof(*elt2));        // effective type is now struct Elt2
    printf("elt2: %g %s\n", elt2->val, elt2->name);
    //printf("elt: %d %s\n", elt->id, elt->name);    UB: storage now contains an Elt2 object
    free(elt);                                    // only legal use for elt
    return 0;
}

我相信n1570草案的6.5表达式§6允许它:

  

访问其存储值的对象的有效类型是声明的类型   object,如果有的话.87)如果一个值存储到一个没有声明类型的对象中   lvalue的类型不是字符类型,那么左值的类型就变成了   该访问的对象的有效类型以及不修改的后续访问   储存的价值。如果将值复制到没有使用声明类型的对象中   memcpy或memmove,或者被复制为字符类型数组,然后是有效类型   用于该访问的修改对象以及不修改该访问的后续访问   value是复制值的对象的有效类型(如果有的话)。

附注87:

  

87)分配的对象没有声明的类型。

问题:

是否重用已分配的内存来存储适合该内存的 符合C的

2 个答案:

答案 0 :(得分:2)

如果没有,那将是灾难性的。很多人使用这些技巧在__soapCall()上实现自己的细粒度内存管理。

所以,是的,这正是您引用的标准段落的内容。请注意,它仔细地选择了这些词。它说

  

如果某个值存储在无声明类型 ...

的对象中

这个没有声明类型的属性在对象的生命周期内没有变化,因此该规定适用于任何时候将新值写入其中。

如果由于一些奇怪的原因委员会想要说有效类型只能改变一次,他们会说类似

  

如果某个值存储在无效类型 ...

的对象中

答案 1 :(得分:1)

唯一正确的答案是完全源自标准的答案。

没有通过标准,我会说,&#34;是的,你的假设是正确的&#34;。我这样说是因为没有它,就不可能实现自己的内存管理器。我认为如果没有{C},就不能在C中实现malloc