... Который явно имеет место только для 2 символов и 1 int (указатель на int в реальности, но в любом случае) ...
Уже неверно.Массивы не указатели.Ваша структура содержит пространство для 2 char
с и 1 int
.Там нет указателя какого-либо вида там.То, что вы объявили, по существу эквивалентно
struct test {
char a;
int v;
char b;
};
Нет большой разницы между массивом из 1 элемента и обычной переменной (есть только концептуальная разница, то есть синтаксический сахар).
... Но вы можете вызвать malloc таким образом, чтобы он содержал 1 символ и столько целых, сколько вы хотели (скажем, 10) ...
Э-э ... Если вы хотите, чтобы он содержал 1 char
, почему вы объявили свою структуру с 2 char
s ???
В любом случае, чтобы реализовать массив гибкого размера какчлен структуры, вы должны поместить свой массив в самый конец структуры.
struct test {
char a;
char b;
int v[1];
};
Затем вы можете выделить память для вашей структуры с некоторой «дополнительной» памятью для массива в конце
struct test *ptr = malloc(offsetof(struct test, v) + sizeof(int) * 10);
(Обратите внимание, как offsetof
используется для вычисления правильного размера).
Таким образом, он будет работать, давая вам массив размером 10 и 2 char
s в структуре (как заявлено).Он называется "взломом структуры" и критически зависит от того, является ли массив самым последним членом структуры.
В версии C99 языка C появилась специальная поддержка "struct hack".В C99 это можно сделать как
struct test {
char a;
char b;
int v[];
};
...
struct test *ptr = malloc(sizeof(struct test) + sizeof(int) * 10);
Что здесь происходит за кулисами?Выделяет ли компьютер 2 + 4 (2 символа + указатель на int) байтов для стандартного "struct test", а затем еще 4 * 9 байт памяти и позволяет указателю "ptr" помещать любые данные, которые ему нужны, в эти дополнительныебайт?
malloc
выделяет столько памяти, сколько вы просите выделить.Это всего лишь один плоский блок сырой памяти.Больше ничего не происходит "за кадром".В вашей структуре нет никакого "указателя на int" любого типа, поэтому любые вопросы, которые включают "указатель на int", вообще не имеют смысла.
Этот трюк работает только тогда, когда внутри находится массивstruct?
Ну, в этом весь смысл: получить доступ к дополнительной памяти, как если бы она принадлежала массиву, объявленному как последний член структуры.
Еслимассив не последний член структуры, как компьютер управляет выделенным блоком памяти?
Он ничего не управляет.Если массив не является последним членом структуры, то попытка работать с дополнительными элементами массива приведет к удалению членов структуры, объявленной после массива.Это довольно бесполезно, поэтому «гибкий» массив должен быть последним членом.