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