编译器如何为程序分配内存?

时间:2015-09-14 07:24:53

标签: c memory-management compiler-construction

假设我在C中编写程序,如:

Code: [1 global var, main(with local vars), 3 functions(with local vars)]

鉴于将在堆栈帧上进行函数调用,编译器如何一眼就知道要分配多少内存?

编译器是否出错并且程序出现内存不足错误?或者编译器是否总是分配精确或额外的内存?

它是否与OS协调?还是自己做出决定?操作系统是否介入?

修改:我找到了一个很有帮助的答案:https://stackoverflow.com/a/19102036/5324086

2 个答案:

答案 0 :(得分:1)

  • 全局变量最终位于.data.bss
  • main和函数最终在程序存储器中,通常称为.text
  • 计算堆栈使用量绝不是编译器的责任。它所做的只是创建将变量推送/弹出到堆栈的函数,但它不会为您计算某些最坏情况。但是,编译器可以通过使用CPU寄存器或函数内联来优化代码,从而尽量减少堆栈使用。
  

鉴于将在堆栈帧上进行函数调用,编译器如何一眼就知道要分配多少内存?

它不知道。堆栈分配在运行时完成,程序员有责任确保程序不会耗尽堆栈内存。

  

编译器是否出错并且程序出现内存不足错误?或者编译器是否总是分配精确或额外的内存?

在您的示例中,所有编译器分配的是全局变量的内存,该变量最终位于data / bss段而不是堆栈中。编译器/链接器知道它可以为data / bss使用多少RAM,并希望在你耗尽内存时告诉你。

答案 1 :(得分:1)

通常应该注意三个内存位置。

数据段(和BSS段),全局变量和静态变量所在的位置。编译器可以在编译时知道所有全局变量和静态变量的大小,并告诉加载程序在程序启动时分配内存。如果内存不足,程序将无法启动。

堆。使用malloc和类似函数的分配使用此段。如果内存不足,标准库会尝试增长,如果失败,malloc会返回NULL指针。

堆栈。调用函数时,会在此处分配局部变量和参数的空间,并在函数返回时取消分配。如果没有足够的内存,它会增长到最大大小(通常是可配置的)。如果它不能增长或达到最大值,则抛出Stack Overflow异常或信号(Unix上的SIGSEGV)。

编辑:当然,程序指令在其他段(文本)中,并且它的大小在编译时也是已知的,如数据段。