当前位置: 首页 > 知识库问答 >
问题:

malloc和全局变量声明将它们的变量分配到C中的何处?[副本]

陆烨磊
2023-03-14

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

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

最后,有没有关于C语言如何与底层硬件交互的资料?我在网上找到的都是与C语法有关的,但我太noob了,不太会看编译器的书。

共有1个答案

柳涵映
2023-03-14

请考虑以下示例:

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指向从堆中提取的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的输出,您可以识别哪些部分对应于在这些地址加载的段。这是留给读者的一个摘录:-)

  •  类似资料:
    • 局部变量使用关键字 def 来声明,其只在声明它的地方可见 . 局部变量是 Groovy 语言的一个基本特性. 例子 13.2 . 使用局部变量 def dest = "dest" task copy(type: Copy) { form "source" into dest }

    • 问题内容: 我想制作一个可以在整个应用程序中访问的自定义对象的全局数组(AppDelegate,ViewController类,TableViewController类等)。我已经研究了一种解决方法,但没有找到答案。我曾尝试将数组设置为公共范围,但是收到了编译器警告,提示当我尝试在其他文件中访问该数组时,出现错误提示 我将如何使该数组可被应用程序中的所有文件全局访问,我将在哪里实例化该数组? 问题

    • 问题内容: 如何在JavaScript中声明全局变量? 问题答案: 如果必须在生产代码中生成全局变量(应避免使用),请 始终 明确 声明它们: 虽然可以通过省略来定义全局变量(假设没有同名的局部变量),但这样做会生成 隐式 全局,这是一件不好的事情,并且在 严格模式下 会产生错误。

    • 我在typescript中声明了一个全局变量,类似于:global。test=“something”我尝试这样做,我得到错误属性“test”在类型“Global”上不存在。

    • 问题内容: 我在一个组件(在应用程序中加载的第一个组件)中初始化了翻译对象。所有其他组件都需要相同的对象。我不想在每个组件中重新初始化它。怎么回事?使它可用于窗口范围并没有帮助,因为我需要在方法中使用它。 请提出针对这些问题的通用解决方案,而不是针对国际的解决方案。 问题答案: 为什么不尝试使用Context? 您可以在任何父组件中声明一个全局上下文变量,并且可以在组件树中通过来访问此变量。您只需

    • 问题内容: 我有这样的代码: 有什么方法可以在一处定义全局变量并使所有函数一次访问该变量?不利用更多? 问题答案: 该数组可以代替使用: 从手册: 包含对所有变量的引用的关联数组,这些变量当前在脚本的全局范围内定义。变量名是数组的键。 如果您有一组需要一些公共变量的函数,那么带有属性的类可能是一个不错的选择,而不是全局的: