具有动态节点大小的C链表

时间:2019-02-25 18:30:45

标签: c list pointers dynamic linked-list

我试图在C语言中创建一个链表,其中每个节点在程序启动时都有用户输入的特定大小。我已经想到了一个结构:

struct ListNode{

    char * str;

    struct ListNode * next_node;

};

,但是每个节点的大小是固定的。有什么想法吗?

非常感谢。

2 个答案:

答案 0 :(得分:1)

似乎您需要节点每次更改的数据大小。您可以通过使用一个固定大小的节点来实现此目的,该节点拥有一个指向动态分配的数据的指针。

请注意,在下面的示例中,结构大小保持为sizeof(void *)+ sizeof(node *) 但是分配给每个节点的数据大小会根据用户输入而改变。

typedef struct Dnode
{
    void* data;
    struct Dnode* next;
}Dnode;

Dnode* CreateDnode(size_t data_size_bytes)
{
    Dnode* newNode = NULL;

    newNode =  malloc(sizeof(Dnode));/*allways the same*/
    if(NULL == newNode)
    {
        return NULL;
    }
    newNode->data =  malloc(data_size_bytes);/*changes by input*/
    if(NULL == newNode->data)
    {
        return NULL;
    }
    newNode->next = NULL;
    return newNode;
}

答案 1 :(得分:0)

听起来像您正在寻找“柔性数组成员”功能,即将不完整的数组放置在结构的末尾:

struct ListNode {
  struct ListNode *next;
  char data[];
};

分配方式如下:

struct ListNode *node = malloc(sizeof *node + data_size_bytes);

然后,我们可以将node->data[i]中的值从i0存储在data_size_bytes - 1中。整个结构和数据都在一个线性块中。

请注意,具有弹性成员的结构不能用作数组元素类型。

在ISO C标准于1999年添加灵活数组成员之前,这是使用大小为1的数组作为流行的“结构黑客”来完成的。如果您不得不在C90中工作,它将像这样:

struct ListNode {
  struct ListNode *next;
  char data[1];
};

现在sizeof ListNode包含一个元素数组,很可能是用于对齐的填充。例如,在具有四个字节指针的系统上,大小很可能为八。如果我们使用相同的malloc行,则会分配过多的内存。用于C90结构破解的正确malloc表达式:

#include <stddef.h>

struct ListNode *node = malloc(offsetof(struct ListNode, data) + data_size_bytes);

与灵活的数组成员功能不同,struct hack没有形式上明确定义的行为。只是“如果可行就行”。