编写getline()实现 – Valgrind错误

我必须重新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); } 

如果你想测试一个主要的function:

 #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); } 

感谢任何帮助或提示。

你的算法很糟糕:

  1. 您将缓冲区保留在分配内存中
  2. 您不使用结构重新组合变量
  3. 你使用魔法数字remaining[i] == 10
  4. 你使用递归你可以堆栈溢出return get_next_line(fd) 。 没关系,我没有读好你有一个尾递归,只是一定要对你的编译进行优化。
  5. 你有Spaghetti代码。
  6. 等等

你应该用更好的逻辑重写你的整个函数首先使用这个结构:

 #include  #include  #include  #include  #define GNL_SIZE 4096 struct gnl_context { char buffer[GNL_SIZE]; size_t i; size_t read; }; char *get_next_line_r(int fd, struct gnl_context *gnl_context); char *get_next_line(int fd); static char *read_buffer(struct gnl_context *gnl_context, char *str, size_t *size) { size_t i = gnl_context->i; while (i < gnl_context->read && gnl_context->buffer[i] != '\n') { i++; } size_t j = i - gnl_context->i; char *ret = realloc(str, *size + j + 1); if (ret == NULL) { return NULL; } memcpy(ret + *size, gnl_context->buffer + gnl_context->i, j); *size += j; ret[*size] = '\0'; gnl_context->i = i; return ret; } char *get_next_line_r(int fd, struct gnl_context *gnl_context) { char *str = NULL; size_t size = 0; loop: if (gnl_context->i == gnl_context->read) { ssize_t ret = read(fd, gnl_context->buffer, GNL_SIZE); if (ret <= 0) { return str; } gnl_context->read = (size_t)ret; gnl_context->i = 0; } char *tmp = read_buffer(gnl_context, str, &size); if (tmp == NULL) { return str; } if (gnl_context->i != gnl_context->read) { gnl_context->i++; return tmp; } str = tmp; goto loop; } char *get_next_line(int fd) { static struct gnl_context gnl_context; return get_next_line_r(fd, &gnl_context); } int main(void) { char *str; while ((str = get_next_line(0)) != NULL) { printf("%s\n", str); free(str); } } 

我担心这条线:

 remaining = remaining + i + 1; 

remaining是指向已分配缓冲区的指针。 在这一行,你破坏它,这意味着你不能再free()它了。