这可能是一个关于 StackOverflow 的简单问题,但它让我抓狂。
让我们以维基百科为例:
void foo (char *bar)
{
char c[28];
float myVar = 10.5;
printf("myVar value = %f\n", myVar);
memcpy(c, bar, strlen(bar));
printf("myVar value = %f\n", myVar);
}
int main (int argc, char **argv)
{
foo("my string is too long !!!!! \x10\x10\xc0\x42");
return 0;
}
如果我们运行这段代码(禁用所有编译器选项),输出为:
myVar value = 10.500000
myVar value = 96.031372
到目前为止一切正常,一旦 memcpy 到达 c[27],就会在 myVar 空间上写入。
现在假设我们更改变量 myVar 的定义位置:
float myVar = 10.5;
char c[28];
输出保持不变,这怎么可能?不应该在“帧指针”空间内写入溢出值。此外,假设我打印这个变量的内存地址,现在的输出是:
myVar value = 10.500000
myVar value = 10.500000
这怎么可能,这像量子力学吗(只是个玩笑)?不是应该重写“帧指针”并使程序崩溃吗?
最佳答案
尽管这是未定义的行为,并且每个编译器的行为可能有所不同,但在较低级别上它是有意义的。
根据您的操作系统和硬件,您应该为堆栈保留大约 2Mb 的保留内存(并不总是如此,但通常足够正确)。
根据您的系统(和 CPU),您可能正在堆栈“前面”写入 - 您正在为您自己的堆栈和程序使用保留的内存上写入,即使您没有“声明” “还没有。
如果您位于堆栈边缘或者您的 CPU 使用不同类型的内存地址解析方案(CPU 中有一部分将程序的指针转换为实际内存地址),这可能会非常糟糕。 .特别是在堆栈内存朝不同方向运行或使用堆栈链表的系统上。
关于c - 堆栈溢出 C 变量位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44166833/