Yes, the general idea of the hack is valid, but at least as I read it, you haven't implemented it quite correctly. This much you've done right:
f = malloc(num + sizeof(foo) + MAX_COMMENT_SIZE );
f->data = f + 1; // is this OK?
But this is wrong:
f->comment = f + 1 + num;
Since f
is foo *
, the f+1+num
is computed in terms of sizeof(foo)
-- i.e., it's equivalent to saying f[1+num]
-- it (attempts to) index to the 1+num
th foo
in an array. I'm pretty sure that's not what you want. When you allocate the data, you're passing sizeof(foo)+num+MAX_COMMENT_SIZE
, so what you're allocating space for is num char
s, and what you (presumably) want is to point f->comment
to a spot in memory that's num char
s after f->data
, which would be more like this:
f->comment = (char *)f + sizeof(foo) + num;
Casting f
to a char *
forces the math to be done in terms of char
s instead of foo
s.
OTOH, since you're always allocating MAX_COMMENT_SIZE
for comment
, I'd probably simplify things (quite) a bit, and use something like this:
typedef struct foo {
char comment[MAX_COMMENT_SIZE];
size_t num_foo;
char data[1];
}foo;
And then allocate it like:
foo *f = malloc(sizeof(foo) + num-1);
f->num_foo = num;
and it'll work without any pointer manipulation at all. If you have a C99 compiler, you can modify this slightly:
typedef struct foo {
char comment[MAX_COMMENT_SIZE];
size_t num_foo;
char data[];
}foo;
and allocate:
foo *f = malloc(sizeof(foo) + num);
f->num_foo = num;
This has the additional advantage that the standard actually blesses it, though in this case the advantage is pretty minor (I believe the version with data[1]
will work with every C89/90 compiler in existence).