下面是一个函数,它返回一个字符指针,该字符串指向使用getc(stdin)
初始化的字符串 - 逐个字符。
内存分配方法有什么缺陷吗?当我们不知道要输入的字符串的大小时,这是一种有效的方法,如果不是,请解释。
使用getc(stdin)
- 会导致缓冲区溢出???()
如果我不能使用getc(stdin)
,有什么能帮助我以更有效的方式实现目标?
代码:
char *getstring()
{
char *str = NULL, *tmp = NULL;
int size = 0, index = 0;
int ch = -1;
int length=0;
while (ch!=0)
{
ch = getc(stdin);
if (ch == '\n')
{
ch = 0;
}
if (size <= index)
{
size += 15;
tmp = (char*)realloc(str, size);
if (!tmp)
{
free(str);
str = NULL;
}
str = tmp;
}
str[index++] = ch;
}
if(size==index)
{
return str;
}
else if(index<size)
{
length=strlen(str);
tmp = (char*)realloc(str,(length+1));
str[index]='\0';
//cout<<"length:"<<length;
str=tmp;
}
return str;
}
答案 0 :(得分:1)
不要重新发明轮子:使用getline(3)
。
示例(来自相同的网址):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
FILE *stream;
char *line = NULL;
size_t len = 0;
ssize_t read;
stream = fopen("/etc/motd", "r");
if (stream == NULL)
exit(EXIT_FAILURE);
while ((read = getline(&line, &len, stream)) != -1) {
printf("Retrieved line of length %zu :\n", read);
printf("%s", line);
}
free(line);
fclose(stream);
exit(EXIT_SUCCESS);
}
答案 1 :(得分:0)
&#34;内存分配方法是否有任何缺陷?&#34; 是的,当重新分配失败时,释放先前的内存指针,为其分配NULL
,然后用tmp
覆盖它,其值为NULL
,然后使用NULL
指针进行翻转。
if (size <= index)
{
size += 15;
tmp = (char*)realloc(str, size);
if (!tmp) // <--- NULL!
{
free(str);
str = NULL;
}
str = tmp; // <--- NULL!
}
str[index++] = ch; // <--- NULL!
但如果realloc
失败,你别无选择,只能优雅地放弃手中的任务。
此外,如果您同时允许0终止符,您将保存几行杂乱的代码和另一个重新分配。并且您不必总是插入'\0'
。
if (size <= index+1) // allow room for string terminator