2011-10-09 196 views
1

为什么有可能超过C中的缓冲区大小达到一定的限制而没有任何错误(分段错误)?超过缓冲区大小?

例如,我用这个代码玩:

#include <stdio.h> 
#include <string.h> 

void function1(char *a) { 
    char buf[10]; 
    strcpy(buf, a); 
    printf("End of function1\n"); 
} 

main (int argc, char *argv[]) { 
    function1(argv[1]); 
    printf("End of main\n"); 
} 

我能够作为一个参数传递最多23个字符,而不是10个字符没有任何错误,但是当我使用24个字符,我收到了分段故障。

我知道用第二十四个字符,我得到了返回值。但以前的13 ??怎么样!

回答

3

您确实收到错误消息。你超过了缓冲区大小,没有发生任何可怕的事情。天真地说,当你超过一个缓冲区时会发生一些可怕的事情。你所期望的没有发生,错误的定义。

我不想变得轻浮。我的观点是严肃的 - 如果你违反规则,你不知道会发生什么。您可能会收到错误消息。它可能显得很好。其他事情可能会发生。原则上,这是不可预测的。它可能会从编译器到编译器,操作系统到操作系统,甚至运行运行。

可能发生在这种情况下的是buf是堆栈中的最后一个东西,以及它没有用于任何关键事物之后的空间。所以使用一些无害的空间后。您最终可能会遇到严重的结构,或者遇到不可写入的页面,从而导致错误。

1

这就是未定义行为的美妙之处

  • 对于C,书写阵列外部是非法
  • 对于操作系统,在未映射地址或在用错误的权限(只读)映射的地址进行写入非法

这些允许做什么过程的想法并不总是完美匹配。

C程序完全有可能做一些完全的脑损伤,使操作系统说“这对我来说没问题”,因为它与正常操作无法区分。

回到你的问题,它可能是前13个字节实际上并没有打扰操作系统(他们写在一个有效的页面)。然后下一个字节可能会触及只读内存或未映射地址,操作系统有机会发现错误。