title: Malloc error: incorrect checksum for freed object - object was probably modified after being freed
body: <p>I've been trying to fix this for 2 days now. I really don't understand what is going on.</p>
  
  <p>I wrote a function to read from a file line per line. It's called <strong>get_next_line()</strong>. This is a project for school, I'm only allowed to use my own C library and <strong>read()</strong>, <strong>malloc()</strong> and <strong>free()</strong>.</p>
  
  <p><a href="https://github.com/pdeguing/get_next_line" rel="nofollow noreferrer">Here is a link to the full GitHub repo</a>, including the instructions. I can only submit <strong>get_next_line.c</strong> and <strong>get_next_line.h</strong> at the end.</p>
  
  <p>Basically, my program seems to run fine if don't handle memory leaks. When I start fixing leaks by using my <strong>ft_strdel()</strong> function, my program still runs fine for most test cases.</p>
  
  <pre><code>void    ft_strdel(char **as)
  {
      if (!as || !*as)
          return ;
      free(*as);
      *as = 0;
  }
  </code></pre>
  
  <p>Yet, if I pass it through the advanced unit test we have at school, I have different errors. They seem to appear randomly sometimes as I can pass 3 times in a row and get a malloc error the 4th time.</p>
  
  <p>The current version seems to handle all memory leaks. Thus, I have this error from the filechecker:</p>
  
  <blockquote>
    <p>get_next_line_tests(43165,0x7fff9e83d340) malloc: <strong>*
    error for object 0x7fe0e3403748: incorrect checksum for freed object -
    object was probably modified after being freed.
    *</strong> set a breakpoint in malloc_error_break to debug</p>
  </blockquote>
  
  <hr>
  
  <h2>Here is the full function:</h2>
  
  <pre><code>#include "get_next_line.h"
  
  static t_list   *get_current_node(const int fd, t_list **line_list)
  {
      t_list      *tmp;
  
      tmp = *line_list;
      while (tmp)
      {
          if ((int)tmp-&gt;content_size == fd)
              return (tmp);
          tmp = tmp-&gt;next;
      }
      return (NULL);
  }
  
  static t_list   *create_new_node(int fd, t_list **line_list)
  {
      t_list  *new;
  
      new = ft_lstnew("\0", fd);
      ft_lstadd(line_list, new);
      return (new);
  }
  
  char            *read_until_newline(int fd)
  {
      char    buf[BUFF_SIZE + 1];
      char    *tmp;
      char    *stack;
      int     ret;
  
      if (read(fd, buf, 0) &lt; 0)
          return (NULL);
      stack = ft_strnew(1);
      if (!stack)
          return (NULL);
      while ((ret = read(fd, buf, BUFF_SIZE)) &gt; 0)
      {
          buf[ret] = '\0';
          tmp = ft_strjoin(stack, buf);
          ft_strdel(&amp;stack);
          stack = tmp;
          if (ft_strchr(buf, '\n'))
              break;
      }
      return (stack);
  }
  
  int             get_index_newline(char *str)
  {
      int     i;
  
      i = 0;
      while (str[i] &amp;&amp; str[i] != '\n')
          i++;
      return (i);
  }
  
  int     get_next_line(const int fd, char **line)
  {
      static t_list   *line_list;
      t_list          *current;
      char            *buffer;
      char            *tmp;
      int             index_newline;
  
      if (fd &lt; 0 || line == NULL)
          return (-1);
      current = get_current_node(fd, &amp;line_list);
      if (!current)
          current = create_new_node(fd, &amp;line_list);
      if (!ft_strchr(current-&gt;content, '\n'))
          buffer = read_until_newline(fd);
      else
          buffer = ft_strnew(1);
      if (!buffer)
          return (-1);
      if (!ft_strlen(buffer) &amp;&amp; !ft_strlen(current-&gt;content))
          return (0);
      tmp = current-&gt;content;
      current-&gt;content = ft_strjoin(tmp, buffer);
      if (tmp)
          ft_strdel(&amp;tmp);
      if (buffer)
          ft_strdel(&amp;buffer);
      index_newline = get_index_newline(current-&gt;content);
      *line = ft_strsub(current-&gt;content, 0, index_newline);
      tmp = current-&gt;content;
      current-&gt;content = ft_strsub(tmp, index_newline + 1, ft_strlen(tmp) - index_newline - 1);
      if (tmp)
          ft_strdel(&amp;tmp);
      return (1);
  }
  </code></pre>
  
  <p>Feel free to comment on any beginner error I could be doing in my code. Please note however that I have to follow a certain norm, that explain my variable declarations and initializations. I cannot use <em>for</em> loops. And have many restrictions like those.</p>
  
  <p>Protecting my <strong>ft_strdel()</strong> calls with <em>if</em> statements was my last attent at solving the issue, obviously it failed and it's useless.</p>
  
  <p>EDIT:</p>
  
  <p>I handle multiple <em>fd</em> by using a <em>static linked list</em>. Each node contains a string with the last read buffer (whatever is left from the reading after substracting the most recently read line). And each node contains an int to store the <em>fd</em> it was read from. This way, I loop through the list until I find the corresponding <em>fd</em> to check for preexisting reading. If no node is returned, it means I have nothing stored for the specific fd so I'll just create a new node.</p>
  
  <p>I hope you have answers! I'm not a regular user on Stack Overflow, I did my best to format my post and be specific. Tell me if I need to edit something. </p>
  
  <p>And thanks for your help!</p>