这是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的?
答案 0 :(得分:2)
如果没有,那将是灾难性的。很多人使用这些技巧在__soapCall()
上实现自己的细粒度内存管理。
所以,是的,这正是您引用的标准段落的内容。请注意,它仔细地选择了这些词。它说
如果某个值存储在无声明类型 ...
的对象中
这个没有声明类型的属性在对象的生命周期内没有变化,因此该规定适用于任何时候将新值写入其中。
如果由于一些奇怪的原因委员会想要说有效类型只能改变一次,他们会说类似
如果某个值存储在无效类型 ...
的对象中
答案 1 :(得分:1)
唯一正确的答案是完全源自标准的答案。
没有通过标准,我会说,&#34;是的,你的假设是正确的&#34;。我这样说是因为没有它,就不可能实现自己的内存管理器。我认为如果没有{C},就不能在C中实现malloc
。