我有以下代码:
int main(int argc, char *argv[])
{
char ch[10];
printf("String 10 max. :: "); gets( ch );
printf("String: %s\n", ch);
return 0;
}
当我使用"12345678"
作为ch
运行时,它运行良好。奇怪的是我和"123456789012345678901234567890"
一起跑!第二个printf
将所有字符串(30个字符)打印到屏幕上。
为什么会这样?为什么我的代码没有崩溃?
感谢您的时间,
阿兹特克
答案 0 :(得分:1)
缓冲区溢出是未定义的行为。它可能会崩溃,但没有人保证。在大多数编译器中,堆栈会逐渐减少,因此您可能会覆盖main
的返回地址,但是对printf
的调用不会覆盖您的字符串。
答案 1 :(得分:0)
缓冲区溢出只会导致"崩溃" (如果您正在尝试从尚未映射的页面读取/写入)(即分段错误)。在这种情况下,内存管理单元会捕获错误。
如果您还没有到达页面的末尾,就像在您的示例中那样,从操作系统/处理器的角度来看,此时的内存仍然有效 - 您只是覆盖了可能被另一个变量使用的内存。
答案 2 :(得分:0)
您没有看到任何效果,因为您没有更多本地变量,将代码更改为此,您将
int main(int argc, char *argv[])
{
char ch[10];
int i=42;
printf("String 10 max. :: "); gets( ch );
printf("String: %s\n", ch);
printf("i: %d\n", i);
return 0;
}
答案 3 :(得分:0)
通过使用您不应使用的内存,您将进入未定义行为的区域。它今天在你的机器上并没有崩溃。但这种行为可能会在没有警告的情况下改变。
为了它的价值,当我在我的cygwin shell上运行相同的代码时,我得到了
Segmentation fault (core dumped)
答案 4 :(得分:0)
缓冲区溢出的影响完全取决于您覆盖的内容,覆盖它的内容以及随后如何使用覆盖的数据。
缓冲区溢出利用的方法涉及使用溢出来修改函数的返回地址;但是从main()
返回到操作系统可能与从函数返回完全不同。