最新消息:

C语言 存储空间分配

当在 C 中声明一个指针时,与声明其他类型的变量类似,一定量的存储空间会分配给这个指针。通常情况下指针会占用一个机器字长的存储空间,但有些时候它们的大小也有所不同。因此,为了保证代码的可移植性,不应该假设每个指针都占有一个特定大小的存储空间。指针变量的大小通常与编译器的设定以及某些特定的 C 实现中的类型界定符有关。必须要记住的一点是: 当声明一个指针时,仅仅只是为指针本身分配了空间,并没有为指针所引用的数据分配空间。而为数据分配存储空间有两种方法: 一种是直接声明一个变量;另一种是在运行时动态地分配存储空间(例如: 使用 malloc 或 realloc)。

当声明一个变量时,编译器会根据变量的类型预留足够的内存空间。变量的存储空间是系统自动分配的,但此存储空间不会在程序的整个生命周期中永久存在,这一点在处理自动变量时尤为重要。自动变量是一种在进入或离开一个模块或函数时其存储空间能够自动分配和释放的变量。例如: 在函数 f 中,iptr 的赋值为变量 a 的地址,当函数 f 返回时,iptr 变成了一个悬空指针。为什么会这样?因为当函数 f 返回时,变量 a 已经从函数栈中弹出,变成了一个不合法的变量。

int f(int **iptr) {
 int a = 10;
 *iptr = &a;
 return 0;
}

在 C 语言中,当想要动态分配存储空间时,我们会得到一个指向一个堆存储空间的指针。此存储空间由我们自行管理,并且会一直存在,除非我们显式地将它释放。例如: 在下面这段代码中用 malloc 分配的存储空间会一直有效直到调用函数 free 来释放它。所以,当函数 g 返回时此存储空间仍然有效,这一点与之前自动分配存储空间的变量完全不同。参数 iptr 是一个指向我们想要改变其内容的对象的指针(此对象也是一个指针),所以当 g 返回时,iptr 指向由 malloc 申请的地址空间。

#include <stdlib.h>
int g(int **iptr) {
 if ((*iptr = (int *)malloc(sizeof(int))) == NULL)
 return -1;
 return 0;
}

有些时候,我们甚至会认为指针和动态存储空间分配是 C 语言领域中不太好的特性。特别是当生产了由动态内存分配所造成的内存泄漏问题时。内存泄漏问题的产生是由于动态分配了内存空间,但从未释放它(甚至在程序不再使用此数据空间时都不释放它)造成的。特别是在重复执行代码时,这种泄漏问题会表现得尤为严重。好在我们可以采用统一的内存管理方法来大大减少此类问题。

一种统一的内存管理方法例子就是本文所用到的数据结构实例。每种实例所遵循的理念是: 由用户来管理存储空间以及与存储空间相关的实际的数据结构,而数据结构自身只用于维护数据内部变量的存储空间分配。所以,在数据结构中,只使用指针所指向数据变量,而不是此数据的私有副本。这种应用的一个重要意义在于,一个数据结构的实现并不依赖于它所存储的数据的类型和大小。同时,多个数据结构能够以单个数据形态表现,这个特性在组织大量数据时非常有用。

初始化可能会涉及很多步骤,其中之一便是内存分配。销毁数据结构通常包括删除它所有的数据,并释放数据结构所用到的内存。释放数据结构的内存往往也包含释放与数据结构本身相关联的所有内存。这里有一个例外,那就是让用户自己管理数据的存储。之所以每个数据结构在初始化的时候都需要使用由用户提供的初始化函数,是因为数据存储的管理实际上是一种与具体应用相关的操作。

好了,C语言 存储空间分配 就分享到这里,非常感谢你的来访。如果你很喜欢本站,请不要忘记收藏本站,以便下次继续访问;也可以 关注站长微博 随时获取最新动态。你的支持就是我最大的动力!

转载请注明:爱维科斯 » C语言 存储空间分配

支付宝打赏支付宝打赏 微信打赏微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者