【问题标题】:C Linked List with dynamic node size具有动态节点大小的 C 链表
【发布时间】:2019-07-19 05:36:21
【问题描述】:

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

struct ListNode{

    char * str;

    struct ListNode * next_node;

};

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

非常感谢。

【问题讨论】:

  • 什么大小?这个“节点”有两个固定大小的字段。
  • 这是一个 XY 问题。最终目标是什么?
  • 目前您的struct 有一个指针,它可能指向不同大小的字符串。但从技术上讲,这些不是struct 的一部分,因此不包括它们的大小。为什么这对你来说还不够好?
  • variable length array 中不能有 struct,但可以有 flexible array member
  • @cchatz 你很可能必须有一个指向动态分配的存储桶的指针

标签: c list pointers dynamic linked-list


【解决方案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));/*always 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;
}

【讨论】:

  • 您好,感谢您的帮助!这行得通。有没有办法整个节点都有这个data_size_bytes?
  • 你可以自己分配一块内存并管理漏洞——也就是说你可以只分配大小,并决定例如前 8 个字节——取决于你的电脑架构将被使用对于下一个 ptr,其余部分将保存您的数据。但是 Size 的大小必须大于 sizeof(void*) 才能保存下一个 ptr 并维护一个列表@cchatz
【解决方案2】:

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

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

这是这样分配的:

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

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

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

在 ISO C 标准在 1999 年添加灵活数组成员之前,这是使用大小为 1 的数组作为流行的“struct hack”完成的。如果您被限制在 C90 中工作,则如下所示:

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

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

#include <stddef.h>

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

与灵活的数组成员特性不同,struct hack 没有正式定义好的行为;它只是“如果有效就有效”的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    相关资源
    最近更新 更多