C++ 当c++;使用的程序堆栈大小是否已确定?

C++ 当c++;使用的程序堆栈大小是否已确定?,c++,c,stack,C++,C,Stack,我知道最大堆栈大小通常在链接上是固定的(可能在windows上就是这样) 但是我不知道什么时候使用的程序堆栈大小(不是最大堆栈大小只是使用的大小)被固定到操作系统上。编译?链接?执行 像这样: int main(){ int a[10]; return 0;} 该程序只使用10*sizeof(int)堆栈。那么,堆栈大小是固定的吗 最重要的是。如果堆大小在malloc或free时更改?在对问题的回答中,我提供了以下信息: BSS/数据段包含所有全局变量,默认情况下初始化为特定值或零。此段是可执

我知道最大堆栈大小通常在链接上是固定的(可能在windows上就是这样)

但是我不知道什么时候使用的程序堆栈大小(不是最大堆栈大小只是使用的大小)被固定到操作系统上。编译?链接?执行

像这样:

int main(){ int a[10]; return 0;}
该程序只使用10*sizeof(int)堆栈。那么,堆栈大小是固定的吗


最重要的是。如果堆大小在malloc或free时更改?

在对问题的回答中,我提供了以下信息:

BSS/数据段包含所有全局变量,默认情况下初始化为特定值或零。此段是可执行映像的一部分。在加载时,堆段被添加到该文件中;但是,它不是一个“段”,而是作为加载的BSS/数据段的扩展而分配的额外数据量。同样,堆栈“段”不是真正的段,而是添加到BSS+堆段。堆栈向下增长,而堆向上增长。如果这些重叠(使用了更多堆且堆栈仍在增长),则会出现“内存不足”错误(堆)或“堆栈溢出”(堆栈)-这可以通过使用段寄存器(Intel)触发硬件生成的异常或使用软件检查来检测


这是布置分段的传统方式。想想旧的英特尔芯片,所有progeram数据必须为64KB。对于更现代的芯片,通常使用相同的布局,在这种布局中使用32MB的地址空间,但只使用实际需要的物理内存。因此,堆栈可能相当大。

在加载程序时,堆栈大小不会显式提供给操作系统。相反,操作系统使用的机制是(如果MMU支持的话)

如果您试图访问操作系统尚未授予的内存,MMU将生成一个由操作系统处理的页面错误。操作系统检查页面错误的地址,或者通过创建新的内存页来扩展堆栈,或者,如果耗尽了堆栈限制,则将其作为堆栈溢出处理

考虑以下在x86和Linux上运行的程序:

void foo(void) {
    volatile int a = 10;
    foo();
}

int main() {
    foo();
}
由于无限递归和堆栈溢出,它会出现故障。它实际上需要无限堆栈才能完成。加载程序时,操作系统分配初始堆栈并将其写入
%rsp
(堆栈指针)。让我们看看
foo()
反汇编:

push   %rbp
mov    %rsp,%rbp         <--- Save stackpointer to %rbp
sub    $0x10,%rsp        <--- Advance stack pointer by 16 bytes
movl   $0xa,-0x4(%rbp)   <--- Write memory at %rbp
callq  0x400500 <foo>
leaveq 
retq 
推送%rbp

mov%rsp,%rbp它是由操作系统在执行进程时分配的。FWIW,堆栈大小不是固定的,它会根据需要在运行时扩展,但堆栈限制是固定的。如果您的程序只使用40字节的堆栈(对于运行时系统,加上多一点),并且操作系统默认为进程分配8MB的堆栈(就像Linux一样),你还有将近8MB的堆栈。这个问题是非常不明确的IMO。考虑把每个问号放在一个合适的地方,也就是说,在一个完善的和可读的问题的结尾。例如,“所以”不是问题,“如果大小固定”也不是问题。。。“那么,如果大小是固定的”也不是问题!!!