malloc和全局变量声明在C中将它们的变量分配给哪里?

时间:2014-06-19 01:42:10

标签: c memory-management malloc

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

此外,全局变量(例如int x = 5)将在何处存储到内存中?

最后,是否有任何材料可以讨论C语言如何与低级硬件交互?我在网上找到的都与C语法有关,但我太习惯读编译器了。

如果不清楚,请告诉我。

3 个答案:

答案 0 :(得分:4)

考虑这个例子:

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的调用堆栈中。它的生命周期受限于该函数中的执行持续时间。 (即一旦函数返回,变量就不再存在,并被删除。)

  • 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/cat0x4000000x60b000中映射了0x60c000的三个部分。

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

答案 1 :(得分:0)

全局变量和静态变量位于数据段

使用malloc()分配的内存位于中。

函数中的自动变量位于堆栈中。

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

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

答案 2 :(得分:-2)

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

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