Звучит так, как будто вы ищете функцию «элемента гибкого массива», при которой неполный массив помещается в конец структуры:
struct ListNode {
struct ListNode *next;
char data[];
};
Это выделяется как:
struct ListNode *node = malloc(sizeof *node + data_size_bytes);
Тогда мы можем сохранить значения в node->data[i]
для i
от 0
до data_size_bytes - 1
.Вся структура и данные находятся в одном линейном блоке.
Обратите внимание, что структура с гибким элементом не может использоваться в качестве типа элемента массива.
До добавления стандарта ISO C гибкийчлен массива в 1999 году, это было сделано как популярный "struct hack" с использованием массива размером 1. Если вы ограничены работой в C90, это выглядит так:
struct ListNode {
struct ListNode *next;
char data[1];
};
Теперь sizeof ListNode
включаетмассив из одного элемента, и , вполне вероятно, заполнение для выравнивания.Например, в системе с четырьмя байтовыми указателями размер вполне вероятно равен восьми.Если мы используем одну и ту же строку malloc
, мы выделим лишнюю память.Правильное malloc
выражение, которое нужно использовать для взлома структуры C90:
#include <stddef.h>
struct ListNode *node = malloc(offsetof(struct ListNode, data) + data_size_bytes);
В отличие от функции члена гибкого массива, взлом структуры не имеет формально четко определенного поведения;это просто то, что «работает, если работает».