【发布时间】:2016-05-22 12:14:17
【问题描述】:
我浏览了以下代码,但找不到问题所在。函数getsxnremem() 使用fgets() 获取最多为len 字符的字符串,用空终止符覆盖换行符(如果有的话),然后重新调整内存大小以适应字符串。反正就是这个想法。
以下代码有时有效,有时会崩溃。过去我已经发生过很多次这种情况,我通常会发现问题,但这次我花了太长时间。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned getsxnremem(char **str, unsigned len){
unsigned l, flag = 1;
free(*str);
char *buff;
if ((*str = malloc(len)) == NULL) return 0;
if(fgets(*str, len, stdin) == NULL) { free(*str); return 0; }
l = strlen(*str);
if (l && ((*str)[l-1] == '\n')) { *(str)[l-1] = '\0'; flag = 0; }
if ((buff = realloc(*str, l + flag)) == NULL){ free(*str); return 0; }
*str = buff;
return (l - 1);
}
int main(void){
char *buff = NULL;
unsigned l = getsxnremem(&buff, 256);
printf("%s\n%u chars long.", buff, l);
}
【问题讨论】:
-
您应该检查来自
fgets()的返回值。如果它得到 EOF,则可能没有有效的字符串来运行strlen()—malloc()返回的内存不能保证是一个以 null 结尾的字符串。这是对不从realloc()收集返回值的问题的改进,尽管当正在使用的空间缩小时重新分配分配将是一个不寻常的实现。 -
如果字符串没有以新行结尾,你重新分配到它的字符串长度。那是空终止符短 1 个字节,将返回错误的长度,并且 printf 可能会读取分配的内存并输出垃圾!添加
else ++l;修复 -
@king_nak 你是对的。我更新了代码来处理这个问题。主要错误仍然存在。谢谢!
-
@JonathanLeffler 谢谢。我更新了代码以检查 fgets() 的返回值并使用 realloc() 的返回值。不幸的是,问题仍然存在。