Stack Overflow C变量位置

时间:2017-05-24 19:18:12

标签: c stack-overflow

这可能是一个关于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

这怎么可能,这就像量子机制(只是一个玩笑)?是不是想重写“帧指针”并使程序崩溃?

1 个答案:

答案 0 :(得分:0)

虽然这是未定义的行为,并且每个编译器可能表现不同,但在较低级别上它是有意义的。

根据您的操作系统和硬件,您应该为堆栈提供大约2Mb的预留内存(并非总是如此,但通常都足够)。

根据您的系统(和CPU),您可能正在写“堆叠” - 您正在写入为您自己的堆栈保留的内存以及您的程序的使用,即使您没有“声明” “它还没有。

如果您处于堆栈边缘或CPU使用不同类型的内存地址解析方案(CPU中有一部分将程序的指针转换为实际内存地址),这可能会非常糟糕。特别是在堆栈内存向不同方向运行的系统上,或者使用堆栈的链表。