Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory leak with getline and strsep

Tags:

c

memory-leaks

Get a memory leak while using getline together with strsep. I know strsep modifies line - could this be the cause? That line is not freed correctly.

  FILE *file = fopen("keywords.txt", "r");
  if (file) {
    char* line = NULL;
    size_t len = 0;
    ssize_t read;

    while ((read = getline(&line, &len, file)) != -1) {  // Line 35

      char *token;
      while ((token = strsep(&line, "\t")) != NULL) {
        // Do stuff
      }

    }

    free(line);
    fclose(file);
  }

Valgrind returns this:

==6094== 4,680 bytes in 39 blocks are definitely lost in loss record 7 of 7
==6094==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6094==    by 0x51AEBB4: getdelim (iogetdelim.c:66)
==6094==    by 0x4009B3: read_keywords (main.c:35)
==6094==    by 0x400959: renew_init (main.c:64)
==6094==    by 0x400A48: main (main.c:68)

If I comment out strsep, there's no memory leak.

Tips?

like image 695
Olle Härstedt Avatar asked Feb 24 '15 00:02

Olle Härstedt


1 Answers

When you pass &line to strsep, it will change the value of line. At the end of the inner loop, line will be NULL and free(line) will do nothing. This will also cause getline to allocate a new buffer instead of reusing the current one.

You should copy line to a new variable, e.g. char *line2 = line; and pass &line2 to strsep.

like image 118
interjay Avatar answered Sep 18 '22 12:09

interjay