是的,这个黑客的一般想法是有效的,但至少就我的阅读而言,你没有完全正确地实现它。你已经做得很对了:
f = malloc(num + sizeof(foo) + MAX_COMMENT_SIZE );
f->data = f + 1; // is this OK?
但这是错误的:
f->comment = f + 1 + num;
由于f
是foo *
,所以f+1+num
是根据sizeof(foo)
计算的——也就是说,它相当于说f[1+num]
——它(试图)索引到数组中的第1+num
个foo
。我非常确定这不是你想要的。当你分配数据时,你传递的是sizeof(foo)+num+MAX_COMMENT_SIZE
,所以你分配空间的大小是num char
,而你(可能)想要的是将f->comment
指向内存中f->data
后面num char
的位置,更像是这样:
f->comment = (char *)f + sizeof(foo) + num;
将f
转换为char *
会强制使用char
而不是foo
进行数学计算。
另一方面,由于您始终为comment
分配MAX_COMMENT_SIZE
,我可能会简化事情(相当)并使用类似于此的东西:
typedef struct foo {
char comment[MAX_COMMENT_SIZE];
size_t num_foo;
char data[1];
}foo;
然后像这样分配它:
foo *f = malloc(sizeof(foo) + num-1);
f->num_foo = num;
而且它可以在没有任何指针操作的情况下工作。如果您有一个C99编译器,可以稍微修改一下:
typedef struct foo {
char comment[MAX_COMMENT_SIZE];
size_t num_foo;
char data[];
}foo;
并分配:
foo *f = malloc(sizeof(foo) + num);
f->num_foo = num;
这样做的额外优点是标准实际上认可它,尽管在这种情况下,优点相当小(我相信带有data [1]
版本将与现有的每个C89/90编译器一起工作)。
data
和comment
),无法直接使用该技术。 - Jonathan Leffler