在C(或C ++)的链表实现中,指针变量的节点大小和生命周期是多少?例如:
struct node
{
int data;
struct node *next;
}*ptr=NULL;
现在我想知道节点的大小:它是4个字节,若然,怎么样?
其次,指针存在多长时间:整个程序的执行?
最后,调用*ptr
实例变量或数据成员或对象是否合适?
答案 0 :(得分:4)
通常不可能知道节点的大小。但是,对于特定平台和库集,您可以在编译时知道节点的大小。
sizeof(struct node)
将告诉您节点的大小。请注意,它可能不是节点组合中所有成员的实际大小。有时,填充是必要的,以使结构中的成员在正确操作所需的内存对齐边界上对齐。
此外,指针没有特定的大小。它们足够大以容纳所需的内存地址,但这是它们必须满足的唯一要求。 32位和64位环境之间的指针大小存在显着差异,即使不在同一硬件上的两个支持的位环境之间切换,不同的硬件平台可能具有不同的内存要求存储指针值。
你得到的“存储指针的4个字节”来自于流行的误解,即所有使用C的计算机都是Intel CPU,Pentium系列芯片只能运行32位代码。当时这是一个不真实的假设,现在假设它同样是不正确的。
即使考虑到这一点,结构的数组也可能需要在数组元素填充之间进行正确的内存对齐。因此,即使您知道结构的大小,也无法确保X
元素数组适合X * sizeof(struct node)
字节的内存区域。
使用sizeof(...)
查找您所寻求的答案,但要确保您想要占用的所有内容都在sizeof(...)
运算符中。
就指针的生命而言,只要程序运行,它就会存在;但是,node->next
中存储的值可能实际上不会引用有意义的地址。 node->next
旨在保存一个地址,但有太多方法可以使node->next
指向不指定满足{{1}需求的位模式开头的地址}}。
C语言的这个“问题”在后来的语言中得到了某种程度的修正,意味着通过使指针类型的操作无法进行“改进”。相反,语言允许指针操作的安全子集,这意味着你真的没有指针(所以他们称之为引用)。 Java和C#是两种这样的语言,但是有许多语言拒绝对指针进行真正危险的操作。
将指针调用为变量的实例是不恰当的,因为它实际上是一个包含内存地址的变量。没有严格的要求它保存的存储器地址包含一个满足指针“类型”的位模式。这只是C ++保留的遗留C问题之一,以便与C兼容。此外,实例变量倾向于建议面向对象的术语,C不能(以其默认形式)提供面向对象的保证,因此应用面向对象编程术语到C是不合适的。
同样,struct不是一个类,结构的成员与一个类的成员的规则略有不同。最大的“稍微不同”的规则是结构的成员通常是公共可访问的,除非你真的非常小心地从程序的其余部分隐藏结构的声明(这将需要很多C体操做和制作你的程序仍然有用。)
答案 1 :(得分:2)
节点的大小取决于您的计算机和编译器。使用sizeof(struct node);
获取它。
它不是4个字节。在32位环境中,它为8(int
为4个字节,struct node *
为4个字节)。
ptr
贯穿整个程序。 ptr
是一个全局变量。
ptr
是实例变量,而*ptr
表示内存ptr
指向。
答案 2 :(得分:0)
Sizeof是一个编译时操作。节点是一种结构。因此,节点的大小是结构中所有成员大小的总和。 所以你有一个整数和一个指针。节点的大小是整数的大小+指针的大小。 生命周期:内存是动态分配的。直到你打电话给免费节点。如果您执行删除操作,那么我们习惯于使用好的程序员样式来释放为该节点分配的内存。