Bor*_*der 8 c++ stack-overflow visual-studio
请考虑以下代码(仅用于演示目的):
#include <iostream>
int main()
{
char pixels[4][1280][720]; // Big enough to cause a stack overflow on my machine
for (unsigned int i = 0; i < 4; i++)
{
for (unsigned int j = 0; j < 1280; j++)
{
for (unsigned int k = 0; k < 720; k++)
{
pixels[i][j][k] = i + j + k;
}
}
}
std::cout << pixels[2][640][360];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据这个问题的答案,最大堆栈大小由visual studio设置.
假设它可以警告用户潜在的堆栈溢出,我是否正确?(我自己尝试了这个并没有得到警告)
PS:我问的唯一原因是因为我看到很多关于SO的问题可以通过这样的警告来防止(是的,我知道不是每个SO用户都使用VS).
And*_*ico 11
在已/analyze
提供标志的版本中,它已经存在:
C:\>cl /EHsc /analyze stack.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
stack.cpp
c:\stack.cpp(3) : warning C6262: Function uses '3686412' bytes of stack: exceeds /analyze:stacksize '16384'. Consider moving some data to heap.
Run Code Online (Sandbox Code Playgroud)
prefast
DDK/WDK附带的工具会产生类似的警告.
当然,这是一个非常简单的静态检查(如果函数的堆栈使用率高于某个阈值).它不会尝试检测递归调用或通过调用链添加总静态使用量.
编译器几乎可以发出任何警告,但在这种情况下,编译器很难给出真正有意义的警告.
特别是,在链接时间之前不会真正选择堆栈大小.编译器在链接器之前运行,因此它基本上不可能知道在运行链接器时可能选择的堆栈大小.因此,如果编译器要发出警告,那么它可以做的最好的事情就是假设某些"合理的"堆栈大小将被选中,并将警告基于违反该规则.
一个足够智能的链接器可能会发出这样的警告,但它需要相当多的智能.特别是,当链接器看到它时,堆栈分配看起来像(机器代码表示):
sub esp, 123456 ; or sub rsp, 123456 in 64-bit code.
Run Code Online (Sandbox Code Playgroud)
链接器必须找到堆栈指针被操纵的每个位置,并检查所涉及的数字的大小以有意义地发出警告.要做到这一点,它基本上必须弄清楚代码是什么,数据是什么,并反汇编和检查代码(但不是数据,可能会反汇编为无意义的代码).这可能是可能的,但可能有些不平凡,而且肯定超出了连接器通常做或使用的事物的范围.
归档时间: |
|
查看次数: |
456 次 |
最近记录: |