2
struct thing { 
    int x;
    thing* next;
} 

显然,大小是 ,sizeof(int)+sizeof(thing*)但什么是sizeof(thing*)???? 嗯,它是指向包含 int 的结构的指针的大小加上指向另一个包含 int 的结构的指针的大小和指向另一个结构的指针的大小,该结构的大小为...... ......

所以我猜事物的大小一定是无限的。(当数学专业的学生拿起一本编程书时会发生这种情况。他把一切都推向了逻辑极端并感到困惑。)

4

4 回答 4

2

结构尺寸

请注意,thing *您所指的 100% 与 无关struct thing。这是C;你的标签是这样说的。你可以这样写来使代码编译干净:

typedef struct thing thing;
struct thing
{
    int    x;
    thing *next;
};

的最小尺寸struct thingsizeof(int) + sizeof(thing *),但结构可以比这更大。实际上,在我的(64 位)机器上,结构的大小为 16 字节,尽管只有 4 个字节。这是因为地址必须是 8 字节对齐的,所以在和指针sizeof(int)之间有 4 个字节的填充。int

8字节对齐

你能解释一下“8字节对齐”是什么意思吗?

许多 CPU 要求 N 字节基本类型应存储在 N 的倍数的地址中。因此,1 字节char变量可以存储在任何地址,但 2 字节short变量必须存储在2的倍数,4字节int变量必须存储在 4 的倍数的地址中,等等。对于某些机器,尤其是 RISC 架构,如果您尝试读取错误的对齐方式,则会收到 SIGBUS 信号(和核心转储)。对于其他人,您最终会让 CPU 进行多次读取和位旋转以获得正确的结果,但比数据正确对齐时要慢得多。编译器知道这些很昂贵,并确保它们不会违反规则。并且编译器在必要时在结构中引入填充,除了结构的开头之外的任何地方,以确保结构中的元素正确对齐,并且结构类型数组的元素将正确对齐。

考虑一个 64 位编译器和数据结构:

struct list
{
    struct list *next;
    int          data;
};

即使单个struct list可能只有 12 个字节(8 个字节用于指针,4 个字节用于数据),编译器将在末尾添加 4 个字节的填充,这样如果您有这些结构的数组,则数组中的第二项将在 8 字节的倍数上正确对齐(需要,因为地址是 64 位,8 字节数量)。

无限大小

大小显然是 sizeof(int)+sizeof(thing*),但是 sizeof(thing*) 是什么???嗯,它是指向包含 int 的结构的指针的大小加上指向另一个包含 int 的结构的指针的大小和指向另一个结构的指针的大小,该结构的大小为...... ......

所以我猜事物的大小一定是无限的。

这里没有无限的倒退。结构的大小和指向结构的指针的大小是两个非常不同的东西。C 不允许递归类型:

struct xyz { int data; struct xyz nested; };   /* Invalid C and C++ and ... */

这将需要无限量的内存,甚至虚拟内存也无法模拟(计算机的主内存中没有足够的位来容纳无限大的数据结构的大小,更不用说无限大的结构本身了)。

但是问题中的结构不包含结构;它包含一个指向结构的指针。C 标准保证结构的所有地址大小相同(POSIX 提出了更严格的要求——指向所有对象的所有指针和指向函数的指针必须大小相同)。所以指向结构的指针的大小是固定的——32 位编译为 4 个字节,64 位编译为 8 个字节(实际上,即使理论上可能存在异常)。并且结构的大小是固定的和有限的。

于 2013-11-01T05:56:01.470 回答
1

不,不,不,sizeof(struct thing*)只是指向结构所需的指针的大小,而不是结构中可能存在的任何内容。(例如,考虑空指针的情况。)

于 2013-11-01T05:52:01.543 回答
1

不,指针的大小是固定的。所以事物的大小是 sizeof (int) + sizeof (pointer)。

挑剔者的角落:

常见的 CPU 架构中的指针大小为 4 或 8 字节,具体取决于 CPU 架构。

然而,一些不常见的架构(DSP 芯片、奇怪的微控制器、PDP-10 和其他面向字的架构)具有不同大小的指针。

此外,在一些不常见的体系结构中,指向不同大小对象的指针本身具有不同的大小,例如 sizeof(char*) != sizeof(int*)。

此外,一些体系结构允许面向位寻址,因此可以获取位域的地址,这通常是不允许的。(C 标准不允许这样做,但可以作为供应商扩展来完成。)

于 2013-11-01T05:52:12.653 回答
1

指针的大小不依赖于它所指向的指针。对于您的系统,指针将是一个字的大小,因此是 4 或 8 个字节。

于 2013-11-01T05:52:15.303 回答