2

我的问题是关于 4GB 可寻址系统的内存管理
char *p = NULL;
它是否占用任何内存?
如果是这样,堆或堆栈在哪里,有多少?也说说char **p=NULL;

4

3 回答 3

8

在典型的 32 位系统上,它占用 4 个字节。

假设您的示例是某个函数中局部变量的定义,则这些字节是从堆栈中获取的。虽然:

  • 如果变量没有在其他地方使用,编译器可能会从生成的代码中完全删除它;
  • 如果该变量仅在本地使用并且不占用其地址,则可以将其放入寄存器中,因此它不会占用“常规”内存。

相反,如果它是一个全局变量(或者,一般来说,一个具有静态存储持续时间的变量),那么在大多数系统上都有一个特殊的内存区域(与堆栈和所谓的堆分开)用于它们。通常它只是在写时复制模式下直接从可执行映像映射的内存区域。所以这里的 4 个字节都在这个特定的内存区域中,在可执行文件内部的空间中。

这同样适用于char **p,根据原则,它没有理由比 更大或不同char *


顺便说一句,如果char * p或者char ** p是聚合数据类型(通常是 a struct)的一部分,它们占用的空间来自struct分配的任何地方 - 如果struct变量是局部变量,它来自堆栈,如果它是动态分配malloc的堆,如果它是全局的,它来自全局的特殊内存区域。请记住,在谈论structs 占用的空间时,有关填充的其他考虑因素也会发挥作用。


请注意,所有这些都是对“典型”32 位系统有效的考虑因素;没有什么能阻止一些奇怪的建筑char **在尺寸上有所不同char *(尽管我认为没有任何理由这样做)。不过,您可以使用sizeof运算符执行直接检查。

就标准而言,我认为对指针大小施加的唯一限制是任何指向数据的指针都可以在void *不丢失信息的情况下相互转换(实际上,该标准从未提及堆栈或寄存器)。此外,请记住,只要“可观察行为”与标准要求的内容一致,编译器就可以做任何它想做的事情,因此标准规定的这些实现细节并不能真正保证,尽管有更多细节可以在您使用的编译器的文档中找到。

于 2012-08-14T13:35:46.730 回答
1

如果没有上下文,变量的两个版本p通常会分别占用一个char*和一个char**的内存,这要么是自动(“堆栈”),要么是静态(“全局”)存储。所需的大小不大于 a 的大小void*(通常是一个机器字)。

总是允许编译器表现得“好像”这个变量存储在内存中,但如果它可以直接替换它的值,它可能会完全删除该变量。从这个意义上说,不能绝对保证您的 C 构造会产生任何特定的具体机器代码。

于 2012-08-14T13:36:41.737 回答
0

指针只是一个可以保存地址的普通变量。无论在哪里char *创建变量,它都会使用内存,无论变量的值是什么。在 32 位系统上,指针的典型大小是 32 位,在 64 位机器上是 64 位。喜欢intlong

于 2012-08-14T13:40:36.757 回答