超过缓冲区大小?
问题描述:
为什么有可能超过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 ??怎么样!
答
您确实收到错误消息。你超过了缓冲区大小,没有发生任何可怕的事情。天真地说,当你超过一个缓冲区时会发生一些可怕的事情。你所期望的没有发生,错误的定义。
我不想变得轻浮。我的观点是严肃的 - 如果你违反规则,你不知道会发生什么。您可能会收到错误消息。它可能显得很好。其他事情可能会发生。原则上,这是不可预测的。它可能会从编译器到编译器,操作系统到操作系统,甚至运行运行。
可能发生在这种情况下的是buf
是堆栈中的最后一个东西,以及它没有用于任何关键事物之后的空间。所以使用一些无害的空间后。您最终可能会遇到严重的结构,或者遇到不可写入的页面,从而导致错误。
答
这就是未定义行为的美妙之处。
- 对于C,书写阵列外部是非法
- 对于操作系统,在未映射地址或在用错误的权限(只读)映射的地址进行写入非法
这些允许做什么过程的想法并不总是完美匹配。
C程序完全有可能做一些完全的脑损伤,使操作系统说“这对我来说没问题”,因为它与正常操作无法区分。
回到你的问题,它可能是前13个字节实际上并没有打扰操作系统(他们写在一个有效的页面)。然后下一个字节可能会触及只读内存或未映射地址,操作系统有机会发现错误。