Coding a getline() implementation - Valgrind errors

前端 未结 2 1302
温柔的废话
温柔的废话 2020-12-22 08:24

I have to recode an implementation of the getline() function, but using the file descriptor of the file and not a FILE *. I am only allowed to use

相关标签:
2条回答
  • 2020-12-22 08:32

    Your algorithm is bad:

    1. You keep the buffer in a allocate memory
    2. You don't use a structure to regroup your variable
    3. You use magic number remaining[i] == 10
    4. You use recursive you can stack overflow return get_next_line(fd). Never mind, I didn't read well you have a tail recursive, just be sure to have the optimization on your compile for it.
    5. You have Spaghetti code.
    6. etc.

    You should rewrite your whole function with a better logic first use this structure:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    #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);
      }
    }
    
    0 讨论(0)
  • 2020-12-22 08:48

    I am concerned about this line:

    remaining = remaining + i + 1;
    

    remaining is a pointer to the allocated buffer. On this line, you destroy it, which means that you cannot free() it anymore.

    0 讨论(0)
提交回复
热议问题