title: c function: delete node from singly linked list using only one local pointer variable
body: <p>So I'm stuck trying to solve this exercise from a book (C Programming: A Modern Approach - K.N. King Chapter 17 exercise 6):</p>
  
  <blockquote>
    <p>Modify the delete_from_list function so that it uses only one pointer variable instead of two (cur and prev).</p>
  </blockquote>
  
  <pre><code>struct node {
      int value;
      struct node *next;
  };
  
  struct node *delete_from_list(struct node *list, int n)
  {
      struct node *cur, *prev;
  
      for (cur = list, prev = NULL;
           cur != NULL &amp;&amp; cur-&gt;value != n;
           prev = cur, cur = cur-&gt;next)
          ;
      if (cur == NULL)
          return list;
      if (prev == NULL)
          list = list-&gt;next;
      else
          prev-&gt;next = cur-&gt;next;
      free(cur);
      return list;
  }
  </code></pre>
  
  <p>(The function returns the head of the list)</p>
  
  <p>One way to do it would be to change the first function parameter to a pointer to pointer but that is asked in a following exercise.</p>
  
  <p>I really can't think of a way to solve this using only one local variable without a memory leak or undefined behavior. Something like this:</p>
  
  <pre><code>struct node *delete_from_list(struct node *list, int n)
  {
      struct node *p = list;
  
      if (!p)
          return NULL;
  
      if (p-&gt;value == n) {
          list = list-&gt;next;
          free(p);
          return list;
      }
  
      while (p-&gt;next &amp;&amp; p-&gt;next-&gt;value != n)
          p = p-&gt;next;
  
      if (p-&gt;next)
  //      free(p-&gt;next); // undefined behavior
          p-&gt;next = p-&gt;next-&gt;next; // memory leak
  
      return list;
  }
  </code></pre>
  
  <p>Another way is recursion but I could never think of this by myself. I doubt this is the intention of the exercise since the exercises in this book are not complicated (this is the first one that I can't figure out) and there were only a few simple recursion exercises in a previous chapter. Also I think technically it's not really one local variable because each call of the function gets new variable copies.</p>
  
  <pre><code>struct node *delete_from_list(struct node *list, int n)
  {
      struct node *t;
  
      if (list == NULL)
          return NULL;
      if (list-&gt;value == n) {
          t = list-&gt;next;
          free(list);
          return t;
      }
      list-&gt;next = delete_from_list(list-&gt;next, n);
      return list;
  }
  </code></pre>
  
  <p>So is there any other way to do this?</p>