C语言 K&R中的getop()实现容易发生缓冲区溢出吗?

h5qlskok  于 2023-04-11  发布在  其他
关注(0)|答案(1)|浏览(139)

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

svdrlsy4

svdrlsy41#

缓冲区溢出导致未定义的行为,包括“未崩溃”。
实际上,溢出会导致内存的修改,而不是缓冲区的一部分。是否会导致崩溃取决于内存是什么以及如何使用它。通常溢出会损坏相邻的变量,函数返回地址和调用函数的堆栈帧。如果返回地址被损坏,它会在函数返回时“崩溃”,但你无法控制编译器如何组织内存使用。
例如,在调试构建中,一些编译器添加堆栈填充以辅助错误检测(在调试器中)并不罕见,因此在缓冲区结束之后可能存在未使用的存储器的整个块,其修改将不会导致崩溃(但是调试器可以使用其来检查溢出)。
无论哪种方式,您都可以使用调试器来检查到底发生了什么,但很明显它可能会溢出。

相关问题