1

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

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

现在我想知道节点的大小:是 4 个字节,如果是,怎么做?其次,指针的寿命:在程​​序的整个执行过程中?最后,调用*ptr实例变量或数据成员或对象是否合适?

4

3 回答 3

4

一般不可能知道节点的大小。但是,对于特定平台和库集,您可以在编译时知道节点的大小。

sizeof(struct node)

会告诉你节点的大小。请注意,它可能不是节点内所有成员组合的实际大小。有时,需要填充以使结构内的成员在正确操作所需的内存对齐边界上对齐。

此外,指针没有特定的大小。它们足够大以容纳所需的内存地址,但这是它们必须满足的唯一要求。32 位和 64 位环境之间的指针大小存在巨大差异,即使不在同一硬件上的两个支持的位环境之间转换,不同的硬件平台也可能对存储指针值有不同的内存要求。

您获得“存储指针的 4 个字节”的地方是普遍的误解,即所有使用 C 的计算机都是英特尔 CPU,在奔腾系列芯片中,只能运行 32 位代码。在当时这是一个不真实的假设,现在假设它同样不真实。

即使在考虑到这一点之后,结构的数组也可能需要数组元素之间的填充以进行正确的内存对齐。结果,即使您知道结构的大小,也无法保证X元素数组适合X * sizeof(struct node)字节的内存区域。

用于sizeof(...)找到您寻求的答案,但请确保您想要获取大小的几乎所有内容都在sizeof(...)运算符中。

就指针的寿命而言,只要程序在运行,它就会一直存在;但是,存储在其中的值node->next可能实际上并未引用有意义的地址。 node->next旨在保存地址,但是有太多方法可以欺骗node->next指向未指定满足struct node.

C 语言的这个“问题”在一定程度上在随后的语言中得到了修复,这些语言旨在通过使指针类型操作变得不可能来“改进”C。相反,语言允许指针操作的安全子集,这意味着你真的没有指针(所以他们称之为引用)。Java 和 C# 就是这样的两种语言,但有许多语言否认指针上真正危险的操作。

将指针称为变量的实例是不合适的,因为它实际上是一个保存内存地址的变量。没有严格要求它保存的内存地址包含满足指针“类型”的位模式。这只是那些遗留的 C 问题之一,C++ 保留这些问题是为了与 C 兼容。此外,实例变量倾向于暗示面向对象的术语,而 C 不能(以其默认形式)提供面向对象的保证,因此应用C 的面向对象编程术语是不合适的。

同样,结构不是类,结构成员的规则与类成员的规则略有不同。最大的“略有不同”的规则是结构的成员通常是可公开访问的,除非您真的非常小心地从程序的其余部分隐藏结构的声明(这将需要大量的 C 体操来做你的程序仍然有效)。

于 2013-08-20T03:04:56.627 回答
2
  1. 节点的大小取决于您的计算机和编译器。用来sizeof(struct node);获取。它不是 4 个字节。在 32 位环境中,它是 8(4 字节为int4 字节struct node *)。

  2. ptr整个程序执行过程中的生命。ptr是一个全局变量。

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

于 2013-08-20T03:13:56.563 回答
0

Sizeof 是一个编译时操作。节点是一个结构。所以节点的大小是结构中所有成员大小的总和。所以你有一个整数和一个指针。节点大小是整数大小 + 指针大小。Lifetime:内存是动态分配的。在您调用免费之前,节点一直存在。如果您执行删除操作,我们习惯于释放为该节点分配的内存的良好程序员风格。

于 2013-08-20T03:55:58.203 回答