Странное определение K-> G0 в к.ч (C ++ KDB) - PullRequest
0 голосов
/ 16 ноября 2018

Я посмотрел на определение 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, потому что мы могли бы освободить память, выделенную для struct (sizeof(G[1])==1 и sizeof(F*)==8).

Я думаю, что определение должно быть исправлено с G G0[1] до G* G0.Где я не прав?

1 Ответ

0 голосов
/ 19 ноября 2018

Когда вы имеете дело с объектом в 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, поскольку у них есть некоторый пул памяти.Выше приведен лишь упрощенный пример того, как это может работать.

...