Да, общая идея взлома является действительной, но, по крайней мере, когда я ее читаю, вы ее не реализовали совершенно правильно. Это много вы сделали правильно:
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
thfoo
в массиве. Я почти уверен, что это не что вы хотите. Когда вы выделяете данные, вы передаете sizeof(foo)+num+MAX_COMMENT_SIZE
, поэтому вы выделяете пространство для num char
s, и то, что вы (предположительно) хотите, - это указать f->comment
на то место в памяти, которое находится num char
с после f->data
, что было бы более как это:
f->comment = (char *)f + sizeof(foo) + num;
Кастинг f
к char *
заставляет математику быть сделано в терминах char
с вместо foo
с.
Ото, так как вы всегда выделяя MAX_COMMENT_SIZE
для comment
, я бы, наверное, упростить вещи (совсем немного), и использовать что-то вроде этого:
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;
Это имеет дополнительное преимущество в том, что стандарт на самом деле благословляет его, хотя и в этом случае преимущество довольно minor (я считаю, что версия с будет работать с каждым компилятором C89/90).
Как вы знаете, но, вероятно, стоит отметить, гибкий член массива в конце структуры работает только тогда, когда у вас есть один элемент переменной длины. Вопрос имеет два элемента переменной длины ('data' и' comment') и не может легко использовать эту технику. –
В этом случае сохраните 'комментарий' как обычную строку' malloc() '-allocated. –
FWIW, я дал этот ответ перед добавлением поля комментария. При добавлении комментария следуйте совету Донала. –