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 上的brk
或mmap
)。
在 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
的三个部分映射到0x400000
、0x60b000
和0x60c000
。
通过查看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语言基础:作用域规则(局部变量,全局变量,形式参数)全局变量与局部变量在内存中的区别初始化局部变量和全局变量
C语言malloc编译报错:initializer element is not constant(不能将全局变量初始化为一个无法在编译时期确定的值)