C中虚拟内存的组织

Posted

技术标签:

【中文标题】C中虚拟内存的组织【英文标题】:Organization of Virtual Memory in C 【发布时间】:2015-05-25 15:15:15 【问题描述】:

对于以下每一项,它在内存中的存储位置和顺序:全局变量局部变量静态局部变量函数参数全局常量局部常量函数本身(并且是main 一个特例?),动态分配的变量

我将如何进行实验评估,即使用 C 代码?

我知道 全局变量 -- 数据 静态变量 -- 数据 常量数据类型 -- 代码 局部变量(在函数中声明和定义)--堆栈 在主函数中声明和定义的变量 -- stack 指针(例如:char *arr,int *arr)——数据或堆栈 动态分配空间(使用 malloc,calloc)——堆

【问题讨论】:

它是特定于实现的,实际上取决于操作系统,也许还有编译器和链接器。 【参考方案1】:

您可以编写一些代码来创建上述所有内容,然后打印出它们的地址。例如:

void func(int a) 
    int i = 0;
    printf("local i address is %x\n", &i);
    printf("parameter a address is %x\n", &a);


printf("func address is %x\n", (void *) &func);

请注意,函数地址有点棘手,您必须将其转换为 void*,并且在获取函数地址时省略 ()。比较内存地址,您将开始了解图片或事物所在的位置。通常文本(指令)位于底部(最接近 0x0000),堆位于中间,堆栈从顶部开始向下增长。

【讨论】:

问题是关于C的,所以std::cout很难找到。 opps,我的错误,使用 printf() 代替 x 是十六进制的格式字符串,我在上面进行了更改,谢谢【参考方案2】:

理论上

就内存位置而言,指针与其他变量没有什么不同。

局部变量和参数可以分配在堆栈上,也可以直接分配在寄存器中。

常量字符串将被存储在一个特殊的数据部分,但与数据的位置基本相同。

数值常量本身不会存储在任何地方,它们将被放入其他变量或直接转换为 CPU 指令。 例如int a = 5; 会将常量 5 存储到变量 a 中(实际内存与变量相关联,而不是常量),但a *= 5 将生成将a 乘以常量 5 所需的代码。

main 就内存位置而言只是一个与其他任何函数一样的函数。局部变量 main 与任何其他局部变量没有什么不同,main 代码与任何其他函数一样位于代码部分的某个位置,argcargv 与其他任何变量一样只是参数(它们由启动提供调用main)等的代码。

代码生成

现在,如果您想查看编译器和运行时将所有这些东西放在哪里,一种可能性是编写一个小程序,定义其中的一些,然后让编译器生成一个汇编列表。然后您将看到每个元素的存储方式。

对于堆数据,您将看到对 malloc 的调用,它负责与动态内存分配器的接口。

对于堆栈数据,您会看到对堆栈指针(x86 架构上的 ebp 寄存器)的奇怪引用,它们将用于参数和(自动)局部变量。

对于全局/静态数据,您将看到以变量命名的标签。

常量字符串可能会被标记为一个糟糕的名称,但您会注意到它们都进入一个将链接到数据旁边的部分(通常命名为 bss)。

运行时地址

或者,您可以运行此程序并要求它打印每个元素的地址。但是,这不会向您显示寄存器的使用情况。

如果您使用变量地址,您将强制编译器将其放入内存中,否则它本可以将其保存在寄存器中。

还要注意,内存组织取决于编译器和系统。使用 gcc 和 MSVC 编译的相同代码可能具有完全不同的地址和元素,其顺序完全不同。

代码优化器也可能会做一些奇怪的事情,所以我建议先编译您的示例代码并禁用所有优化。 不过,看看编译器为获得大小和/或速度所做的工作可能会很有趣。

【讨论】:

以上是关于C中虚拟内存的组织的主要内容,如果未能解决你的问题,请参考以下文章

如何把电脑c盘虚拟内存调到别的盘

虚拟内存(Virtual Memory)

C盘空间的话,如何将虚拟内存转到D盘,关闭系统还原,关闭休眠...

06 内存(上)划分与组织内存

VMware虚拟机里提示虚拟内存过小,如何处理?

怎样设置虚拟内存的先后顺序