Я смотрю на определение K и макрос KF:
typedef struct k0{
signed char m,a,t;
C u;
I r;
union {G g;H h;I i;J j;E e;F f;S s;struct k0*k;struct{J n;G G0[1];};};
}*K;
#define kG(x) ((x)->G0)
#define kF(x) ((F*)kG(x))
В соответствии с руководством мы можем получить доступ kF(x)[42]
чтобы получить 42-й элемент вектора, но после использования всех макросов должен быть сгенерирован следующий код
F i = ((F*)(x->G0))[42]
Но я думаю, что есть проблема с преобразованием G G0[1]
в (F*) G0
потому что мы могли бы освободить память, выделенную для структуры (sizeof(G[1])==1
а также sizeof(F*)==8
).
Я думаю, что определение должно быть исправлено с G G0[1]
в G* G0
, Где я не прав?
Когда вы имеете дело с объектом в kdb, думайте о структуре K (на самом деле структура k0, так как K на самом деле является указателем на структуру k0) как заголовок списка. G0 действительно отмечает начало того, где начинается список, если ваш объект K действительно влияет на список. Например, список из 16 чисел может быть распределен следующим образом.
K my_list = malloc(offsetof(struct k0, G0) + sizeof(F) * 16);
my_list->t = KF;
my_list->n = 16;
Посмотрите здесь, как структура k0 на самом деле просто занимает начало памяти, и после массива, начиная с G0 [0], выделяется дополнительное пространство для массива, в котором достаточно места для размещения 16-ти чисел с плавающей запятой.
Обратите внимание, что kdb на самом деле не использует malloc, поскольку у них есть некоторый пул памяти. Выше приведен лишь упрощенный пример того, как это может работать.
Других решений пока нет …