c - 堆栈溢出 C 变量位置

标签 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

这怎么可能,这像量子力学吗(只是个玩笑)?不是应该重写“帧指针”并使程序崩溃吗?

最佳答案

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

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

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

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

关于c - 堆栈溢出 C 变量位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44166833/

相关文章:

java - 从内部类访问父方法时出现 StackOverflowError

java - RegEx 换行符遇到 StackOverflowError

c - Linux C 应用程序内存不足

c - 如何重新分配内存?我不断遇到段错误

c - 操作字符变量的位

c - 如何使用 c yajl 进行流式传输

来自堆栈分配的 C++ std::bad_alloc?

c - STM32 VCP驱动——只有优化后指针才会失效

c - C 中的 HTTP 请求语法

c - 如何在使用 C 时找出 Linux 中的剩余堆栈