【发布时间】:2017-05-30 01:38:50
【问题描述】:
我必须重新编码getline() 函数的实现,但使用文件的文件描述符而不是FILE *。我只允许使用malloc() 和free(),以及最多25 行的5 个函数。
我认为我已经正确地完成了这个项目,尽管我是 C 的初学者并且我的代码可能不太好。
当我运行它时,它运行良好,但 valgrind 显示我 definetely lost x bytes, x 取决于文件长度和 READ_SIZE(在标题中定义的宏)。
根据 valgrind 的--leak-check=full,当我 malloc dest 时,str_realloc_cat 函数中存在内存泄漏。我试过但找不到我应该在哪里释放/做其他事情?
下面是我的代码:
char *get_next_line(const int fd)
{
static char *remaining = "";
char *buffer;
ssize_t cread;
size_t i;
i = 0;
if (remaining == NULL)
return (NULL);
if ((buffer = malloc(SOF(char) * READ_SIZE + 1)) == NULL ||
(cread = read(fd, buffer, READ_SIZE)) < 0)
return (NULL);
buffer[cread] = 0;
remaining = str_realloc_cat(remaining, buffer);
while (remaining[i])
{
if (remaining[i] == 10)
{
remaining[i] = 0;
buffer = str_create_cpy(remaining);
remaining = remaining + i + 1;
return (buffer);
}
i++;
}
return (check_eof(fd, buffer, remaining, cread));
}
char *str_realloc_cat(char *rem, char *buf)
{
size_t i;
size_t dest_i;
char *dest;
i = (dest_i = 0);
if ((dest = malloc(SOF(char) * (str_len(rem) + str_len(buf) + 1))) == NULL)
return (NULL);
while (rem[i])
{
dest[dest_i] = rem[i];
dest_i++;
i++;
}
i = 0;
while (buf[i])
{
dest[dest_i] = buf[i];
dest_i++;
i++;
}
dest[dest_i] = 0;
free(buf);
return (dest);
}
char *check_eof(const int fd, char *buffer, char *remaining, ssize_t cread)
{
if (cread == 0)
return (NULL);
if (cread < READ_SIZE)
{
buffer = remaining;
remaining = NULL;
return (buffer);
}
return (get_next_line(fd));
}
char *str_create_cpy(const char *src)
{
char *dest;
size_t i;
i = 0;
if ((dest = malloc(sizeof(char) * str_len(src) + 1)) == NULL)
return (NULL);
while (src[i])
{
dest[i] = src[i];
i++;
}
dest[i] = 0;
return (dest);
}
int str_len(const char *str)
{
size_t i;
i = 0;
while (str[i])
i++;
return (i);
}
如果您想测试,还有一个主要功能:
#define SOF(x) sizeof(x) // Why in the comments
int main(int ac, char **av)
{
int fd;
char *s;
UNUSED(ac);
if (!av[1])
return 1;
fd = open(av[1], O_RDONLY);
while ((s = get_next_line(fd)))
{
printf("%s\n", s);
free(s);
}
close(fd);
}
【问题讨论】:
-
sizeof(char)总是 1,不要用它污染你的代码。 -
使用
#define SOF(x) sizeof(x)- 未显示但推断 - 似乎有点毫无意义。每次通话可以节省 3 个字符的输入,但会造成混淆。不是一个好的权衡。 -
"某个 char 在另一个系统上超过 1 个字节(尽管可能性很小)" 发生这种情况的唯一方法是,如果 C 编译器不符合标准。
sizeof(char)根据 C 标准为 1,它从不依赖于系统。 -
if( !av[1] )是检查是否没有参数的错误方法。虽然av数组是空终止的,但它只能保证av[ac]将为空。ac在某些环境中可能为 0。相反,请使用if( ac < 2 )。我还建议使用传统的argv和argc来表示“参数向量”和“参数计数”。最后从不使用无括号条件和循环,你只是要求一个很难找到的错误。如果要节省垂直空格,请切换到 1TBS 或Stroustrup。 -
琐事 — 使用
int i = 0;并为自己节省一行。不完全是琐事——你有if (remaining[i] == 10),但应该有if (remaining[i] == '\n')。