此C代码编译时没有任何错误/警告。当我运行这个程序时,我可以输入超过16个字符,它很乐意回应我的所有字符。
永远?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 16
int main() {
char* buffer = malloc(BUFFER_SIZE);
while (1) {
bzero(buffer, BUFFER_SIZE);
scanf("%s", buffer);
puts(buffer); // echo
}
free(buffer);
return 1;
}
(编译:“gcc bufferoverflow.c -o buffer -Wall”)
为什么这样有效?什么时候会崩溃?
答案 0 :(得分:4)
基本上,您遇到了“未定义的行为”。
您可以阅读超过分配的内容,因为scanf()
不知道您分配了多少。为避免这种情况,请使用fgets()
中的stdin
,然后使用sscanf()
。
在这种情况下最常见的行为是scanf
只是将字符写入内存。当然不是永远。有些东西会阻止它,如果没有别的话,它会在某个时刻“超过内存结束”,并且在大多数现代系统上,将发生未处理的异常并且程序将崩溃。在嵌入式系统上,您可能只是暂停处理器。
它正在工作,因为没有任何重要的事情超过您分配的缓冲区,因此覆盖它不会产生不利影响。当然,这不一定是,你可能会触及一些合理的事情并且崩溃,或者更糟糕的是,改变程序/系统某些部分的行为而不会崩溃。