getop()的代码-来自K&R 2 ed的第78页-如下:
int getch(void);
void ungetch(int);
/* getop: get next character or numeric operand */
int getop(char s[])
{
int i, c;
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.')
return c; /* not a number */
i = 0;
if (isdigit(c)) /* collect integer part */
while (isdigit(s[++i] = c = getch()))
;
if (c == '.') /* collect fraction part */
while (isdigit(s[++i] = c = getch()))
;
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
(getch
只是getchar
的 Package ,我们可以认为它是一样的)
例如,当用户输入一个20位长整数,而s
的大小仅为10时,没有任何大小检查。
然而,我不能使程序崩溃,即使我将s
的大小定义为2,并且输入是一个非常非常长的1111111...1111111,它只是正确地给予了我inf
。
1条答案
按热度按时间svdrlsy41#
缓冲区溢出导致未定义的行为,包括“未崩溃”。
实际上,溢出会导致内存的修改,而不是缓冲区的一部分。是否会导致崩溃取决于内存是什么以及如何使用它。通常溢出会损坏相邻的变量,函数返回地址和调用函数的堆栈帧。如果返回地址被损坏,它会在函数返回时“崩溃”,但你无法控制编译器如何组织内存使用。
例如,在调试构建中,一些编译器添加堆栈填充以辅助错误检测(在调试器中)并不罕见,因此在缓冲区结束之后可能存在未使用的存储器的整个块,其修改将不会导致崩溃(但是调试器可以使用其来检查溢出)。
无论哪种方式,您都可以使用调试器来检查到底发生了什么,但很明显它可能会溢出。