【发布时间】:2026-01-26 20:45:02
【问题描述】:
在 Brian 和 Dennis 的经典 C 语言书籍“The C Programming Language”的第 1.9 章中,有一段关于函数“getline”的代码,该函数用于将输入文本的下一行复制到一个char 类型字符串并检查溢出。我引用下面的代码:
int getline(char line[], int maxline);
int getline(char s[], int limit)
{
int c,i;
for (i=0; i<limit-1 && (c=getchar())!=EOF && c!='\n'; ++i) /* ** */
s[i]=c;
if (c == '\n') {
s[i]=c;
++i;
}
s[i] = '\0';
return i;
}
问题来了:参数'limit'是行的最大长度,所以数组s[]只能包含从s[0]到s[limit-1]的元素集合。如果变量 c 到 getchar() 的最后一个字符是 '\n' 并且这个字符的索引是 limit-1,那么 'for' 循环中的判断部分会因为 'i==limit-1' 而失败,但不是'c!='\n' (按照从左到右的顺序)。接下来if子句会起作用,因为'c=='\n'',那么s[limit-1]=c,那么++i会将i的值设置为limit。 s[i]='\0' 会溢出,因为 s[limit] 超出了字符串的限制。我的分析对不对?感谢您提供任何有用的答案。
【问题讨论】:
-
"如果变量 c 到 getchar() 的最后一个字符是 '\n' 并且这个字符的索引是 limit-1" - 如果
i已达到 @,则不会读取该字符987654323@。短路布尔 eval 将在getchar()之前中断循环,并进行随后的分配和进一步的比较。 -
是的,你是对的!我错过了这一点。谢谢。
-
实际上有两点会发生这种情况。
标签: c overflow kernighan-and-ritchie