malloc 和全局变量声明在 C 中将它们的变量分配到哪里? [复制]

Posted

技术标签:

【中文标题】malloc 和全局变量声明在 C 中将它们的变量分配到哪里? [复制]【英文标题】:Where does malloc and global variable declaration allocates their variable to in C? [duplicate] 【发布时间】:2014-08-09 10:55:09 【问题描述】:

在一个简单的 C 程序中,如果我 malloc 一个指向变量或数组的点,根据内存映射,这部分内存分配到哪里?我对计算机编程非常陌生,所以我不确定不同的变量在内存中的存储方式是如何不同的。

另外,全局变量(例如int x = 5)将存储在内存中的什么位置?

最后,有没有关于 C 语言如何与低级硬件交互的材料?网上查到的都是C语法相关的,但是编译书我太菜鸟了。

如果不清楚,请告诉我。

【问题讨论】:

您能不能不通过 Google 搜索任何此类信息。不难找到... @AntonH 我很抱歉询问所谓的基础知识,但我发现的信息太多了,我无法理解这一点。希望你能理解。 +1:这个问题有点含糊,但还是很有趣的。 【参考方案1】:

考虑这个例子:

int global_x = 5;
int global_y;

int main()

    int local_a;

    char* buf = malloc(100);

虽然以下描述并非总是如此(特别是在微型嵌入式实现中),但现代平台上的典型程序将按如下布局:

global_x 是一个初始化的全局变量。它通常存储在可执行文件的.data 部分中,当程序加载时,它与程序文本一起位于内存的可读写、不可执行部分中。

global_y 是一个未初始化的全局变量。空间保留在程序的.bss 部分,不占用可执行文件中的空间。加载时它位于与上述类似的部分。

local_a 是一个本地(或“自动”)变量,位于 main 的调用 stack 中。它的生命周期受限于该函数的执行持续时间。 (即一旦函数返回,变量就不再存在,并被丢弃。)

buf 指向从 heap 中提取的 100 字节的动态分配缓冲区。堆是一个内存区域,通常会根据需要扩展以适应应用程序的内存需求。当堆空间耗尽时(由malloc 和支持的库函数确定),将向操作系统请求额外的内存(例如,Linux 上的brkmmap)。


在 Linux 上,您可以查看 /prod/[pid]/maps 以查看进程 [pid] 的内存映射。例如:

$ cat /proc/30009/maps
00400000-0040c000 r-xp 00000000 fd:01 268784                             /usr/bin/cat
0060b000-0060c000 r--p 0000b000 fd:01 268784                             /usr/bin/cat
0060c000-0060d000 rw-p 0000c000 fd:01 268784                             /usr/bin/cat
01a7a000-01a9b000 rw-p 00000000 00:00 0                                  [heap]
365ec00000-365ec20000 r-xp 00000000 fd:01 263066                         /usr/lib64/ld-2.18.so
365ee1f000-365ee20000 r--p 0001f000 fd:01 263066                         /usr/lib64/ld-2.18.so
365ee20000-365ee21000 rw-p 00020000 fd:01 263066                         /usr/lib64/ld-2.18.so
365ee21000-365ee22000 rw-p 00000000 00:00 0 
365f000000-365f1b4000 r-xp 00000000 fd:01 263128                         /usr/lib64/libc-2.18.so
365f1b4000-365f3b4000 ---p 001b4000 fd:01 263128                         /usr/lib64/libc-2.18.so
365f3b4000-365f3b8000 r--p 001b4000 fd:01 263128                         /usr/lib64/libc-2.18.so
365f3b8000-365f3ba000 rw-p 001b8000 fd:01 263128                         /usr/lib64/libc-2.18.so
365f3ba000-365f3bf000 rw-p 00000000 00:00 0 
7f685162b000-7f6857b54000 r--p 00000000 fd:01 302750                     /usr/lib/locale/locale-archive
7f6857b54000-7f6857b57000 rw-p 00000000 00:00 0 
7f6857b6c000-7f6857b6d000 rw-p 00000000 00:00 0 
7fffa6f09000-7fffa6f2a000 rw-p 00000000 00:00 0                          [stack]
7fffa6ffe000-7fffa7000000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

我们看到/usr/bin/cat 的三个部分映射到0x4000000x60b0000x60c000

通过查看readelf -a /usr/bin/cat 的输出,您可以确定哪些段对应于在这些地址加载的段。这是留给读者的练习:-)

【讨论】:

【参考方案2】:

全局变量和静态变量在数据段

malloc() 分配的内存在中。

函数中的自动变量在堆栈中。

这是一个解释进程内存布局的网站:http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/

它并不特定于 C,但它显示了这些不同的内存区域如何位于进程内存中。

【讨论】:

什么是自动变量? 函数中未声明static的局部变量。 虽然“数据段”特别模糊(在磁盘上?在内存中?)malloc 不会从.data 部分中提取,甚至不会从内存映射的同一区域中提取。 【参考方案3】:

所有“malloc”-ed 变量/数组在堆空间中分配内存,而所有其他变量在堆栈中分配内存。

你应该可以在网上找到很多教程。

【讨论】:

静态和全局变量分配在 BSS 中,而不是在堆栈或堆中。 错了。只有局部变量在堆栈上。

以上是关于malloc 和全局变量声明在 C 中将它们的变量分配到哪里? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

C - 声明变量并调用 malloc

c语言怎样声明和定义全局变量

在目标 c 中使用全局变量

为啥在 JavaScript 中将全局变量添加到窗口对象?

C语言基础:作用域规则(局部变量,全局变量,形式参数)全局变量与局部变量在内存中的区别初始化局部变量和全局变量

C语言malloc编译报错:initializer element is not constant(不能将全局变量初始化为一个无法在编译时期确定的值)