这可能是一个关于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
这怎么可能,这就像量子机制(只是一个玩笑)?是不是想重写“帧指针”并使程序崩溃?
答案 0 :(得分:0)
虽然这是未定义的行为,并且每个编译器可能表现不同,但在较低级别上它是有意义的。
根据您的操作系统和硬件,您应该为堆栈提供大约2Mb的预留内存(并非总是如此,但通常都足够)。
根据您的系统(和CPU),您可能正在写“堆叠” - 您正在写入为您自己的堆栈保留的内存以及您的程序的使用,即使您没有“声明” “它还没有。
如果您处于堆栈边缘或CPU使用不同类型的内存地址解析方案(CPU中有一部分将程序的指针转换为实际内存地址),这可能会非常糟糕。特别是在堆栈内存向不同方向运行的系统上,或者使用堆栈的链表。