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

标签 c pointers linked-list nodes

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

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

现在我想知道节点的大小:是不是 4 个字节,如果是,怎么办? 其次,指针在整个程序执行过程中存在多长时间? 最后,将 *ptr 称为实例变量或数据成员或对象是否合适?

最佳答案

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

sizeof(struct node)

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

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

“4 个字节用于存储指针”是由于普遍的误解,即所有使用 C 语言的计算机都是 Intel CPU,属于 Pentium 系列芯片,只能运行 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 体操来做和制作你的程序仍然有效)。

关于c - C 中链表实现中节点的大小和生命周期是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18326234/

相关文章:

pointers - Julia 中的重叠数组 - 带指针的解决方案?

c - 释放循环链表时如何将指针设置为空

c - 使用 typedef 定义的 int 数组的位大小

c - 用位域初始化结构常量数组

c - 这种变量分配是如何工作的?

c - 理解指向赋值 C

c - 了解字符串指针数组

algorithm - 按引用或按值链接列表?

c - 在链表中的另外两个节点之间插入节点

java - 在java中使用链表乘多项式