数组不溢出(C语言)

时间:2017-07-28 23:16:34

标签: c arrays overflow scanf

如果我尝试运行此代码并提供例如“Hello”(超过3个字符)作为scanf的输入,则数组str不会溢出。这对我来说听起来有点奇怪,但当然我错过了一些东西。有谁知道这里的问题是什么?非常感谢!

char str[3];
scanf("%s", str);
printf("%s\n", str);

3 个答案:

答案 0 :(得分:2)

你说,"阵列str并没有溢出"但你怎么知道?您是如何期望溢出显现的?

实际上,数组已经溢出。你刚刚得到了#34;幸运"并且没有(可见的)反响。

理解计算机编程的一个棘手问题是规则的执行可能非常不一致。 (计算机编程与生活在这方面并没有什么不同。)如果交叉路口的信号表示“不要走路”,但是没有车来,所以你无论如何都要过马路,你有多惊讶没有警察立即出现,并写了一张jaywalking票?这基本上就是这里发生的事情。

答案 1 :(得分:1)

我试图运行你的代码,它确实是段错误的:

./main 
ofejnhofewnhouwnofwbeqofenoifwenofwenoubwuiowgebouwegfougewfnbnbboue
ofejnhofewnhouwnofwbeqofenoifwenofwenoubwuiowgebouwegfougewfnbnbboue
Segmentation fault (core dumped)

我不知道你试图传递多少个字符scanf()但是你必须知道有时编译器会在保存的ESP / EIP和初始变量之间执行填充。

特别是,在这里,您要在堆栈上创建一个3字节的内存区域,编译器首先将其四舍五入为4(或者在x64上为8?)。但即便如此,它可能会增加更多空间。

gdb中,disass main给了我:

   0x000000000040057d <+0>: push   %rbp
   0x000000000040057e <+1>: mov    %rsp,%rbp
   0x0000000000400581 <+4>: sub    $0x20,%rsp

sub 0x20是32个字节,显然超过3个字节。

不要指望严格的“虚拟”C到汇编程序指令,现在编译器执行了许多优化和决策,而不是你可能知道的。

试图找到缓冲区和EIP之间的确切字节范围通常需要执行蛮力,但聪明的黑客可能会找到更有趣的方法......; - )

答案 2 :(得分:1)

C运行时不会发出错误/警告消息,但会产生错误的结果。 要检查溢出/下溢是您的责任。