指针与跳过列表混淆的数组

时间:2016-07-19 21:31:04

标签: c arrays pointers skip-lists

我认为我对跳过列表的工作方式有一个基本的了解,但除了作为C-beginner之外,对它们不熟悉让我对几点感到困惑,尤其是列表的初始化。这是我要遵循的代码:

#define MAXSKIPLEVEL 5

typedef struct Node {
    int data;
    struct Node *next[1]; 
} Node;

typedef struct SkipList {
    Node *header;
    int level;
} SkipList;


// Initialize skip list
SkipList* initList() {

    SkipList *list = calloc(1, sizeof(SkipList));

    if ((list->header = calloc(1, sizeof(Node) + MAXSKIPLEVEL*sizeof(Node*))) == 0) {
        printf("Memory Error\n");
        exit(1);
    }

    for (int i = 0; i < MAXSKIPLEVEL; i++)
        list->header->next[i] = list->header;

    return list;
}

我还没有在C中使用指针数组做任何事情,所以我觉得我对它们的工作原理有点了解。如果有人能够帮助我,我会有一些问题。

首先,我做了sizeof(int)得到了4,sizeof(Node*)得到了8,所以我希望sizeof(Node)等于12,但结果是16,为什么会这样?与SkipList的大小相比,其内容大小相同。我把typedef[1]拿出来看看是否有原因,但尺寸仍然是16。

第二,为什么struct Node *next[1]中的[1]?以后list->header->next[i]需要它吗?可以next[i]高于1吗?是不是因为每个节点的指针数量都是可变的,所以你把它变成一个数组,然后再单独增加它?

第三,为什么list->header->next[i] = list->header最初而不是NULL

非常感谢任何建议/意见,谢谢。

2 个答案:

答案 0 :(得分:1)

由于结构填充sizeof数字为16。

许多架构要求强烈偏好指针在某个边界上对齐(例如,4字节边界,8字节边界等)如果指针“未对齐”,它们将失败,或者它们将缓慢执行。您的C编译器可能在您的结构中间插入4个未使用的字节,以便您的8字节指针在8字节边界上对齐,这会导致结构大小增加4个字节。

C FAQ提供了更多解释。

答案 1 :(得分:1)

对于您的第一个问题 - 为什么不是struct其成员大小的大小? - 这是由于 struct padding ,其中编译器(通常出于对齐原因)可能会在struct成员之间或之后添加额外的空格,以便将大小增加到一些基本尺寸的好的倍数(通常是8或16)。没有可移植的方法来强制结构的大小正好与其成员的大小相同,尽管大多数编译器都有一些自定义开关可以翻转来执行此操作。

关于你的第二个问题 - 为什么[1]? - 这里的想法是,当您实际分配节点struct之一时,您将对空间进行过度分配,以便struct末尾的内存可用于指针。通过创建一个长度为1的数组然后分配空间,您可以在语法上方便地访问这个已分配的空间,就像它始终是struct的一部分一样。较新版本的C有一个名为灵活阵列成员的概念已经取代了这种技术;我建议谷歌搜索它,看看是否有帮助。

对于您的最后一个问题 - 为什么list->header->next[i]最初指向list->header而不是NULL? - 没有看到更多的代码,很难说。链接列表结构的许多实现使用这样的某种技巧来避免在实现中对NULL的特殊情况,并且完全有可能在这里使用这种技巧。