D.F*_*kaz 1 c memory-management local-variables static-allocation stack-pointer
假设我们有以下代码:
void foo() {
char buffer[100];
}
Run Code Online (Sandbox Code Playgroud)
在foo()返回之前,C语言中是否有一种(最好是可移植的)方式从运行时堆栈中释放缓冲区(又称添加esp,在程序集中为100 )?
不。您可以在C语言中做的最好的事情就是使用范围:
void foo()
{
{
char buffer[100];
}
}
Run Code Online (Sandbox Code Playgroud)
并依靠编译器buffer在内部范围退出后再次考虑100字节的可用空间。不幸的是,这不是标准所保证的,您需要依赖编译器。例如,在具有8192KB(ulimit -s)堆栈空间的典型Linux计算机上考虑以下程序:
#include <stdio.h>
int main(void)
{
{
char buffer1[8192 * 800] = { 0 };
((char volatile *)buffer1)[0] = buffer1[0];
printf("%p\n", buffer1);
}
{
char buffer2[8192 * 800] = { 0 };
((char volatile *)buffer2)[0] = buffer2[0];
printf("%p\n", buffer2);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
(怪异的转换是为了防止缓冲区变量被优化掉。)
如果不进行优化构建,程序将在某些编译器上溢出可用的堆栈空间。clang -O0例如,将崩溃,但clang -O1将重复使用buffer1内存,buffer2并且两个地址将相同。换句话说,buffer1在范围退出时,某种意义上已被“释放”。
另一方面,即使在,GCC也会进行此优化-O0。