在一个简单的C程序中,如果我malloc
指向一个变量或数组的点,那么这部分内存是根据内存映射分配的?我对计算机编程很陌生,所以我不确定不同的变量在内存中的存储方式不同。
此外,全局变量(例如int x = 5
)将在何处存储到内存中?
最后,是否有任何材料可以讨论C语言如何与低级硬件交互?我在网上找到的都与C语法有关,但我太习惯读编译器了。
如果不清楚,请告诉我。
答案 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上的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
的输出,您可以确定哪些部分对应于在这些地址加载的段。这留给读者一个练习: - )
答案 1 :(得分:0)
全局变量和静态变量位于数据段。
使用malloc()
分配的内存位于堆中。
函数中的自动变量位于堆栈中。
这是一个解释流程内存布局的网站:http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/
它不是特定于C,但它显示了这些不同的内存区域如何位于进程内存中。
答案 2 :(得分:-2)
所有" malloc" -ed变量/数组在堆空间中分配内存,而所有其他变量在堆栈中分配内存。
你应该可以在网上找到很多教程。