在 C(或 C++)中的链表实现中,节点的大小和指针变量的生命周期是多少?例如:
struct node
{
int data;
struct node *next;
}*ptr=NULL;
现在我想知道节点的大小:是 4 个字节,如果是,怎么做?其次,指针的寿命:在程序的整个执行过程中?最后,调用*ptr
实例变量或数据成员或对象是否合适?
在 C(或 C++)中的链表实现中,节点的大小和指针变量的生命周期是多少?例如:
struct node
{
int data;
struct node *next;
}*ptr=NULL;
现在我想知道节点的大小:是 4 个字节,如果是,怎么做?其次,指针的寿命:在程序的整个执行过程中?最后,调用*ptr
实例变量或数据成员或对象是否合适?
一般不可能知道节点的大小。但是,对于特定平台和库集,您可以在编译时知道节点的大小。
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 体操来做你的程序仍然有效)。
节点的大小取决于您的计算机和编译器。用来sizeof(struct node);
获取。它不是 4 个字节。在 32 位环境中,它是 8(4 字节为int
4 字节struct node *
)。
ptr
整个程序执行过程中的生命。ptr
是一个全局变量。
ptr
是一个实例变量,而*ptr
表示内存ptr
指向。
Sizeof 是一个编译时操作。节点是一个结构。所以节点的大小是结构中所有成员大小的总和。所以你有一个整数和一个指针。节点大小是整数大小 + 指针大小。Lifetime:内存是动态分配的。在您调用免费之前,节点一直存在。如果您执行删除操作,我们习惯于释放为该节点分配的内存的良好程序员风格。