k.h 中 K->G0 的奇怪定义 (C++ KDB)

Strange definition of K->G0 in k.h (C++ KDB)

我看过 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])==1sizeof(F*)==8)的内存.

我认为应该将定义从 G G0[1] 更正为 G* G0。我哪里错了?

当您在 kdb 中处理 object 时,将 K 结构(实际上是 k0 结构,因为 K 实际上是指向 k0 结构的指针)视为列表的 header。如果您的 K object 实际上是一个列表,则 G0 确实标记了列表开始的位置。例如,一个包含 16 个浮点数的列表可能会分配如下。

K my_list = malloc(offsetof(struct k0, G0) +  sizeof(F) * 16);
my_list->t = KF;
my_list->n = 16;

在这里查看 k0 结构如何真正占用内存的开头,并且数组的额外 space 是在它从 G0[0] 开始分配的,有足够的空间容纳 16 个浮点数。

请注意,kdb 实际上并不使用 malloc,因为它们有某种内存池。以上只是它如何工作的一个简化示例。