c - 为什么最大堆栈深度不断变化?

标签 c windows

对于以下代码,最后一个输出(最大堆栈深度不断变化):

#include <stdio.h>
#include <windows.h>

int depth=0;

void func(){
    int x=depth;
    printf("%d\n",depth++);
    func();  
    printf("%d\n",x);
}

int main(){
    func();
    return 0;
}

//由 cl /F 1 test.c 编译

第一次是3717 ,第二个是3700 ,第三个是3695 .

我认为对于恒定的堆栈大小,最大堆栈深度应该是恒定的。但为什么会发生变化?

最佳答案

在运行 x86/x64 CPU 的 Microsoft Windows 平台上,为堆栈保留的内存总是以 page 结尾。边界和stack overflow当堆栈增长超出该页面边界时将发生。一页通常是 4096 字节的内存。

Address Space Layout Randomization (ASLR),堆栈也将从页面边界开始,这意味着最大堆栈大小将是页面大小的倍数。默认情况下,堆栈的最大大小为 1 MiB , 即 256 页 4096 字节。

但是,当 ASLR 处于事件状态时,堆栈的起始地址不再位于页面边界上,而是随机的。由于为堆栈保留的内存仍以页面边界结束,这意味着最大堆栈大小是随机的,不再是页面大小的倍数。

最大堆栈大小的这种随机性就是堆栈溢出的时间也是随机的原因。

默认情况下,Microsoft 链接器在启用 ASLR 的情况下构建可执行文件。为了禁用 ASLR,您必须添加 /DYNAMICBASE:NO调用链接器时的选项。之后,无论何时运行程序,堆栈溢出都应该在完全相同的时间发生。

关于c - 为什么最大堆栈深度不断变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60693620/

相关文章:

c - 在c中选择一个随机线程

windows - 克隆存储库导致超时

windows - 如何从文本文件中读取值,然后查找并替换 xml 文件中的值?

python - Django 检查服务器是否已经运行

c - 顶点两次进入 DFS 堆栈

c - "peek"入eventfd内部计数器值不变

c - 无法找到任何有效的 shell。需要在外部终端执行

windows - 通过 Cygwin 通过 "Windows Command"启动 Perl 脚本

MySQL 服务器命令 mysqld 不工作

c - C 中浮点到 24 位整数