2

关于 sizeof 运算符如何计算链表中一个节点的大小,我发现这件事有点棘手和递归。例如,我将以下结构作为列表中的一个节点:

struct ll_core
{
    char c_ll;
    struct ll_core * next;
};

printf("size of struct ll_core = %d\n\n",sizeof(struct ll_core));

它给了我一个答案 8。现在它如何决定大小 8,因为要添加单个结构元素的大小,它会再次遇到相同的结构 ll_core。所以在计算大小时这是一种循环或递归。请原谅我,让我知道我在这样思考时是否遗漏了任何基本的东西。

4

7 回答 7

3

它不再需要结构的大小,因为结构只包含一个指向结构的指针,而不是结构本身。

“指针struct ll_core”的大小与 的大小无关struct ll_core,它们是两种不同的类型。一个是指针,另一个不是。

你不能声明一个“真正的”递归数据结构,因为它是无限的。

于 2013-05-27T08:01:41.547 回答
2

因为要添加单个结构元素的大小,它会再次遇到相同的struct ll_core.

不,它遇到一个指向a的指针struct ll_core。如果它遇到结构本身,那将导致无限大小。编译器知道 a的大小和对齐要求,struct ll_core *甚至struct ll_core对.nextstruct ll_core

于 2013-05-27T08:01:59.853 回答
2

假设您在 32 位机器上运行代码,指针大小将为 4 个字节。由于结构将在字边界上对齐,因此将填充 3 个字节,因此大小将为 8 个字节。

这个结构实际上是这样的,

struct ll_core{
    char       c_11:
    char const byte[3];  //padded bytes for alignment reasons
    struct ll_core *next;
};
于 2013-05-27T08:38:07.003 回答
1
struct ll_core
{
    char c_ll;
    struct ll_core * next;
};

sizeof运算符添加结构成员的大小ll_core。这里是一个字符 ( c_ll) 和一个指针 ( next)。

有关如何计算大小的更多信息。

结构填充:

在 64 位系统中,数据将以 8 字节块的形式读取和写入。因此,当计算结构的大小时,会发生填充。意味着编译器将在结构的成员之间插入一些间隙以“对齐”到架构地址边界。如下所示:

struct ll_core
{
    char c_ll;
    /* 7 bytes of padding */
    struct ll_core * next;
 };

所以这个结构在 64 位系统中的大小将是 16 字节。

结构包装:

您可以通过结构打包来防止编译器进行结构填充。在 GCC 中,它是这样完成的:

struct __attribute__((__packed__)) ll_core
{
    char c_ll;
    struct ll_core * next;
};

现在在 64 位机器上大小将是 9 个字节。

sizeof(char) + sizeof(pointer)

编辑 - 从您的问题来看,您似乎在 32 位机器上运行。在 32 位机器中,数据将以 4 字节块的形式读取和写入。

于 2013-05-27T08:45:57.087 回答
0

如果某些类型在某些地址上对齐,许多处理器会更好地工作。这意味着编译器会在单个char元素之后填充您的结构,以便指针位于本机字边界上。

至于结构中的“递归”,没有,因为该next字段是指向结构的指针,而不是结构本身。

于 2013-05-27T08:02:01.203 回答
0

你错过了重点,仔细看......“下一个”只是一个指针。你不能只做'struct ll_core next'..那是没有*。所以,只要它是一个指针。将仅针对指针的大小计算大小。通常,指针大小为 4。

如果您有任何困惑,请从next中删除*并尝试编译代码。

于 2013-05-27T08:02:06.390 回答
0

有 2 个元素是一个 char(大小 1)和一个指针(大小 4),所以您认为大小为 5,但结构被填充为 4 个字节(字长)。char 被填充到 4 个字节,总共 8 个字节。

于 2013-05-27T08:03:45.327 回答