【问题标题】:Are nodes in a linked list separate structs or part of the same struct?链表中的节点是单独的结构还是同一结构的一部分?
【发布时间】:2019-02-07 05:53:04
【问题描述】:

我在 C 中有一个链表如下:

typedef struct intSet *link;

typedef struct intSet {
    int num;
    link next;
} intSet;

当我打印结构的各个成员的大小时,我得到了以下信息:

sizeof(List) = 8 bytes  //List is a newly created list
sizeof(curr->num) = 4 bytes  // curr is just a node within the list
sizeof(curr->next) = 8 bytes

我的问题是:无论列表中有多少元素,结构本身是否总是具有 8 个字节的大小,或者这 8 个字节仅与第一个节点有关,而列表中的下一个节点不同相同结构的实例?

我问的原因是因为我打算在 PostgreSQL 中将其实现为用户定义的数据类型,因此它需要我声明数据类型的长度是常量还是变量:

CREATE TYPE list (
    internallength = 8? or internallength = variable
    input = ..., output = ... );

如果它是变量,我必须将我的结构表示更改为:

typedef struct intSet {
    int size;
    int num;
    link next;
} intSet;

我怀疑如果节点是分开的并且不是同一结构的不同部分,我可能必须不断更新大小,因为下一个节点的大小可能比最后一个节点大 4 个字节。 任何提示或指示将不胜感激。

【问题讨论】:

  • does the struct itself always have a size of 8 bytes regardless of how many elements we have in the list 结构的大小在运行时不会改变,但我怀疑它的 8 个字节,它应该是 16 个字节。我假设List 是一个指针,所以你得到的是指针的大小,而不是结构的大小。
  • 永远不要typedef(数据)指针。哦,你应该阅读你喜欢的 C 教科书中的指针。

标签: c struct linked-list sizeof singly-linked-list


【解决方案1】:

对 sizeof 的关注不是主要问题,尤其是在 32 位中 sizeof(intSet) 将为 8,而在 64 位中 sizeof(intSet) 将为 32 位。

关于 PostgreSQL,您要存储的对象是一个 int 容器,因此长度可变。因此,您要处理的对象不是 intSet,而是一个包含列表大小和第一个元素的结构。

typedef struct intSet *link;

typedef struct intSet {
    int num;
    link next;
};

struct intSetSized
{
    int size;
    intSet begin;
};

您要声明为udt 中的用户定义类型,即intSetSized

您在列表中添加或删除的每个内容都会调整size

注意如何为对象实现输入和输出函数intSetSizedudt 中给出的示例更加棘手。

【讨论】:

  • 在我的任务中,我将“set”作为字符串检索,所以现在我正在考虑将其作为字符串存储在结构中,而不是像上面那样作为链表存储在结构中这要复杂得多。我正在考虑从这个“集合”(例如“{1, 2, 3}”)创建一个链接列表,所以在这种情况下,我可以在创建操作列表时对字符串进行 palloc,然后使用 malloc 对吗?
  • 根据我在postgresql.org/docs/9.5/static/xtypes.html 中收集的信息,您需要将对象序列化为字符串(转换为 char *)并从字符串反序列化。无论是在 I/O 函数内部还是外部进行从字符串到 int set 的转换,都取决于您。
【解决方案2】:

您的类型link 是一个指针,如果您没有将它与typedef 混淆会更明显。指向的东西是一个单独的struct(它也有自己的next 点等),它需要自己的存储空间。

现在sizeof(curr->next)sizeof(List)指向结构的指针 的大小,而不是struct intSet 的大小。 sizeof(*(curr->next))sizeof(struct intSet) 都是结构本身的大小,即您需要为 single 结构分配的空间量。

sizeof 永远不会遍历指针来找出整个列表的大小。如果需要找出列表的整个大小,需要自己遍历并统计元素,那么总大小为count * sizeof(struct intSet)。不过,您不太可能需要此信息用于链接列表,因为如果您一次分配整个列表,您可以只使用没有 next 链接的数组......

【讨论】:

  • 另请注意,您不能将next(或任何其他)指针存储在数据库中,因为它们仅对那些特定分配有效。
【解决方案3】:

sizeof 的指针在系统中是相同的。在您的情况下,无论它指向什么(无论是 int、char、struct 等),它总是 4 个字节。在您的情况下,它将是 4 个字节。 因此,您的结构大小将始终为 8 个字节(4 个字节用于 int + 4 个字节用于指针)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多