C - Linked Lists - Deleting Head - Segmentation Fault
<p>I am working on a problem for a class and we're learning linked lists in C. I was given a section of code to complete, specifically the delete a node section and I'm having a problem deleting head. Every time I try to delete head I receive a segmentation fault. Can someone tell me what I'm doing wrong?</p>

<p>EDIT2
My teacher wrote everything but the lookup and delete functions.</p>

<p>I have fixed the glaring errors pointed out by the gentleman from Moscow and Mr. Petriuc, however the code still doesn't run. It does compile, but there is still a problem in head.</p>

<p>Here is the full code:</p>

<pre><code>#include &lt;string.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#include "linkedList.h"

// keep an unsorted array of char *'s, strings.

/*
  Create an empty node, return 0 if fail, 1 if succeed
 */
struct node * createNode() {
  struct node *p = (struct node *) malloc(sizeof(struct node));
  if (p == NULL) return 0;

  p-&gt;prev = p-&gt;next = NULL;
  p-&gt;data = NULL;
}


/*
  Lookup string in the list, return pointer to node of first occurence, NULL if not found.
 */
struct node * lookup(struct node *head, char *s) {
  struct node *p;
  for(p=head; p!=NULL; p=p-&gt;next){
    if(strcmp(s,p-&gt;data)==0){
      return p;
    }
  // just like print, but check if strcmp(s, p-&gt;data) == 0, and if so then return p
  }
  return NULL;
}


/*
  Insert new string into the linked list, return 1 if success, 0 if fail.
 */
int insert(struct node **head, char *newS, int insertDuplicate) {
  struct node *p = lookup(*head, newS);

  if (p == NULL || insertDuplicate) {
    // create a new node, put it at the front.
    p = createNode();
    if (p == NULL) return 0;

    // put the string in the new node
    p-&gt;data = (char *) malloc(sizeof(char) * (1 + strlen(newS)));
    if (p-&gt;data == NULL) return 0;
    strcpy(p-&gt;data, newS);

    // note: make changes and use old head before setting the new head...
    p-&gt;next = *head;   // next of new head is previous head

    if (*head != NULL)
      (*head)-&gt;prev = p; // previous of old head is new head

    *head = p;         // set the new head
  }

  return 1;
}

/*
  Remove string from list if found, return 1 if found and deleted, 0 o/w.
 */
int delete(struct node **head, char *s) {
  struct node *p,*pr,*ne;
  // first do a lookup for string s, call lookup.
  p=lookup(*head, s);

  if(p==*head){
    *head = p-&gt;next;
    free(p);
    return 1;
  }

  if(p!=NULL){
     printf("%s",p);
     pr = p-&gt;prev;
     ne = p-&gt;next;

     free(p-&gt;data);
     free(p);

    if(pr==NULL||ne==NULL){
      return 0;
    }
     pr-&gt;next=ne;
     ne-&gt;prev=pr;
  // if lookup returns NULL, done, return 0.
  // if lookup returns p, not NULL,
  // pr = p-&gt;prev, ne = p-&gt;next
  //  set pr-&gt;next to ne, ne-&gt;prev to pr
  //  but what if pr or ne is NULL
  // and note that we need node **head because if delete head,
  // need to update head pointer back in calling function, in
  // here if you want head probably do *head.  like in insert.
  // also, before the pointer to the one you're deleting is gone,
  // free p-&gt;data and p.
    return 1;
  }
  return 0;
}


void print(struct node *head) {
  struct node *p;
  for(p = head; p != NULL ; p = p-&gt;next) {
    printf("%s\n", p-&gt;data);
  }
}
</code></pre>