【问题标题】:how do static and dynamic variables compiled in C静态和动态变量如何在 C 中编译
【发布时间】:2015-04-03 10:24:59
【问题描述】:

为什么编译器不知道 C 中动态变量的地址(例如动态数组)?

是不是因为程序编译前没有声明变量(数组)的大小?

或者,我想,一个更好的问题是:编译器在编译程序时如何分配静态变量(或数组)的地址?

【问题讨论】:

  • 静态和全局变量由编译器在编译时在数据段中生成;未初始化的被放入称为“bss 段”的数据段的一部分,该段用零填充。在运行时分配的变量是堆栈和堆变量。它们的位置取决于创建它们时的内存布局。
  • 什么是“动态数组”?
  • 好吧,从我在讲座中被告知的内容来看,就是当一个地址被声明为 ex int *b 然后你在主函数中调用 *b = malloc(4*sizeof(int)) ,那么这将创建一个大小为 4 的数组。
  • @PeterChung 我认为您的演讲称其为“动态数组”对您没有任何帮助。名称是“堆变量”。正在发生的事情是,当进程启动时,它在其地址空间中被赋予了一个称为“堆”的区域。 C 库具有函数(malloc、free 和friends),可让您从该区域保留内存供您使用。它从低地址向上增长,所以当你调用“malloc”时,它交还给你的内存取决于运行时堆的样子。编译器无法知道它。

标签: c arrays dynamic static compilation


【解决方案1】:

编译器将开始独立编译每个源文件。 当涉及到静态变量时,它将根据其是否初始化将其存储在 .bss 或 .data 部分中。 如果您的主函数正在调用另一个源文件的函数,则所有目标文件的所有段都放在一起称为程序内存映射的东西,被调用函数的地址将是一个“虚拟”地址,在链接期间被替换过程。 静态变量没有导出到链接器,这就是为什么没有其他源文件可以访问另一个源文件的静态变量的原因,因为链接器看不到它。所以想象一下编译器在编译过程中不会抛出错误,当所有目标文件链接在一起时会抛出错误。

如果你想一步一步尝试 使用

将两个源文件编译为目标文件
gcc -c source1.c -o object1.o
gcc -c source2.c -o object2.o

然后把它和

链接起来
ld object1.o object2.o 

如果你想看到 static 只是链接器的一个关键字,你可以这样做

给 source1.c 一个 source2.c 的头文件,其中包含一个名为 test 但没有关键字 static 的变量或数组。在 source2.c 中,您使用关键字 static 定义相同的变量 请不要在 source2.c 本身中包含 source2.c 的标头。然后再做这三个步骤

当你调用 ld 时你应该得到一个链接器错误

【讨论】:

    猜你喜欢
    • 2011-12-09
    • 2023-03-03
    • 1970-01-01
    • 2023-04-10
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多