C 只分配结构的一部分合法吗?

C 只分配结构的一部分合法吗?,c,malloc,language-lawyer,C,Malloc,Language Lawyer,我最近遇到一个使用“酷黑客”的软件,如下所示: #包括 #包括 结构foo{ INTA; char*b; int可选; char庞大[5000]; /*更多的成员*/ }; void myfunc(void){ 结构foo*p; p=malloc(offsetof(struct foo,可选)); 如果(p){ p->a=17; p->b=“你好”; /*用p->a和p->b做动作*/ 自由基(p); } } 其思想是通过只分配实际要使用的struct foo部分来“节省内存” 我看到了许多明

我最近遇到一个使用“酷黑客”的软件,如下所示:

#包括
#包括
结构foo{
INTA;
char*b;
int可选;
char庞大[5000];
/*更多的成员*/
};
void myfunc(void){
结构foo*p;
p=malloc(offsetof(struct foo,可选));
如果(p){
p->a=17;
p->b=“你好”;
/*用p->a和p->b做动作*/
自由基(p);
}
}
其思想是通过只分配实际要使用的
struct foo
部分来“节省内存”

我看到了许多明显的原因来解释为什么这个代码是一个坏主意:如果您对
struct foo
的成员重新排序,或者如果您忘记了允许使用哪些成员,或者如果您意外地分配了
*p
或将其按值传递给函数,那么它肯定会崩溃。(在链接的代码中,对于大多数程序只调用很少几次的函数,每次调用可以节省高达80字节的内存。)


但它实际上是未定义的行为,还是在C标准方面是非法的?如果是这样的话,有没有实际执行的例子,它不会像预期的那样工作?

< P>我不认为标准做出了任何努力来考虑这种模式。在编写标准时,它肯定是通用的,并且受到所有普通实现的支持。虽然没有明显的理由说明任何通用实现都不支持它,但我不知道标准的作者是否希望排除那些客户不需要这种模式的实现的可能性,如果他们注意到分配给指向结构类型的指针的分配地址对他们来说太大,就会发出尖叫。相反,我认为他们期望实现能够有效地处理这样的结构,而没有很好的理由去做其他事情,但他们不想猜测什么是“好的理由”


至于这样的代码是否能可靠工作的问题,没有什么特别的理由不应该这样做,我也不知道有什么特别的情况会导致clang或gcc出现问题,但是现在或将来的版本可能会发现一些“聪明”的优化会失败。

Dup:@p.p:谢谢,我不知道我怎么没找到。我已经投票决定关闭我的。对于一个实际的例子,如果它不起作用,顺便看看,问题中链接的glibc代码必须不再使用这种技术。