C中链表实现中节点的大小和生命周期是多少?

时间:2013-08-20 02:52:32

标签: c pointers linked-list nodes

在C(或C ++)的链表实现中,指针变量的节点大小和生命周期是多少?例如:

struct node
{
  int data;
  struct node *next;
}*ptr=NULL;

现在我想知道节点的大小:它是4个字节,若然,怎么样? 其次,指针存在多长时间:整个程序的执行? 最后,调用*ptr实例变量或数据成员或对象是否合适?

3 个答案:

答案 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)

  1. 节点的大小取决于您的计算机和编译器。使用sizeof(struct node);获取它。  它不是4个字节。在32位环境中,它为8(int为4个字节,struct node *为4个字节)。

  2. ptr贯穿整个程序。 ptr是一个全局变量。

  3. ptr实例变量,而*ptr表示内存ptr指向。

答案 2 :(得分:0)

Sizeof是一个编译时操作。节点是一种结构。因此,节点的大小是结构中所有成员大小的总和。     所以你有一个整数和一个指针。节点的大小是整数的大小+指针的大小。   生命周期:内存是动态分配的。直到你打电话给免费节点。如果您执行删除操作,那么我们习惯于使用好的程序员样式来释放为该节点分配的内存。