Thread: segfault from linked list function

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    6

    segfault from linked list function

    I have the following function that adds a node to the front of a doubly-linked linked list.

    Code:
    #define HEAD list->head
    #define TAIL list->head->prev
    
    ...
    
    void add_front(llist* list, lnode* node) 
    {
    printf("function has been run! \n");
    
      /* new head needs to point to old head as its next. 
       * new head needs to point to old tail as its prev.
       * tail needs to point to new head as its next.
       * old head needs to point to new head as its prev.
       * llist needs to recognize new head as head.
       */
      /* If the list is not empty */
       if(HEAD != NULL) {
        printf("condition is being checked! \n");
        /* if the list contains more than 1 element */
        if(HEAD->next != NULL){
          node->next = HEAD; 
          node->prev = TAIL;
          TAIL->next = node;
          HEAD->prev = node;
        }  
      }
      list->head = node;
     }
    Pretty sure the HEAD and TAIL are being used correctly.
    The function is being used as follows:

    Code:
    llist myList;
    lnode myNode;
    lnode skippy;
    
    int main()
    {
      
      myNode.x = 5;
      myNode.y = 7;
      skippy.x = 1;
      skippy.y = 9;
      myList.head = &myNode;
      
     add_front(&myList, &skippy); 
     printf("myNode.x= %d\n", myNode.x);
     printf("skippy.x= %d\n", skippy.x);
     printf("testing add_front... \n");
     printf("skippy.y= %d\n", myNode.next->y);
     return 0;
    }
    To give some background on the structs, they are defined in a header file as:
    Code:
    /* The node struct.  Has a prev pointer, next pointer, and data. */
    typedef struct _lnode {
    
      struct _lnode *prev;
    
      struct _lnode *next;
    
      int x;
    
      int y;
    } lnode;
    
    /* The linked list struct.  Has a head pointer. */
    typedef struct _llist {
    
      lnode *head;
    
    } llist;
    when I run the test case, I get the following output:
    Code:
    function has been run! 
    condition is being checked! 
    myNode.x= 5
    skippy.x= 1
    testing add_front... 
    Segmentation fault
    Any ideas? I know this is a lot of code to look through, and I greatly appreciate any help received.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    While I can't pinpoint the error right now (it may require the help of a debugger), I do have a suggestion.
    The HEAD and TAIL macros or defines only makes sense inside your add_front function. They're local to the function which is why I would suggest that you define them at the beginning of the function and undefine them at the end. Something like this:

    Code:
    void add_front(llist* list, lnode* node) 
    {
    #define HEAD list->head
    #define TAIL list->head->prev
    /* ... */
    #undef HEAD
    #undef TAIL
    }
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,793
    HEAD->next != NULL

    You check it but never set it - it contains garbage
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    David J. Wheeler

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    6
    The test function has the following line:
    Code:
    myList.head = &myNode;
    Where both myList and myNode have been declared.
    Is that what you are referring to? That looks clean to me, but I'm also the one with the segfault.

    Also, what would anyone recommend for a debugger? I have heard of GDB but I have never used it.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Visual Studio. The best debugger on the earth
    Just kidding, of course, but it's obviously very powerful and feature rich.

    Also, you never set HEAD->next or TAIL->prev, so they might just contain garbage (check your function!).
    And you never initialize all of mynode's members either.
    Last edited by Elysia; 04-16-2008 at 03:58 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    6
    I have considered moving to windows for C, but have yet to make the switch. I'll mess with GDB and see what I can find. Thanks for your help.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    But myHead.head->next is never set to anything.

    GDB is a good debugger - there are also GDB frontends that allow you to use graphics to control GDB - can't think of a name right now, DDD springs to mind, but could be wrong.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    6
    Ah yeah, that function was pretty incomplete. Thanks again for all the info.

    For future reference (dunno if this could every be useful to someone else),
    here is the fixed function:
    Code:
    void add_front(llist* list, lnode* node) {
    
      /* new head needs to point to old head as its next. 
       * new head needs to point to old tail as its prev.
       * tail needs to point to new head as its next.
       * old head needs to point to new head as its prev.
       * llist needs to recognize new head as head.
       */
      /* If the list is not empty */
      if(HEAD != NULL) {
        
        /* if the list contains more than 1 element */
        if(HEAD->next != NULL){
          
          node->next = HEAD; 
          node->prev = TAIL;
          TAIL->next = node;
          HEAD->prev = node;
        }  
        /* there is only 1 element in the list */
        else{
          HEAD->prev = node;
          HEAD->next = node;
          node->prev = HEAD;
          node->next = HEAD;
        }
        list->head = node;
      }
    }
    Last edited by kataya; 04-16-2008 at 04:33 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  2. linked list noob - function create new list
    By dukysta in forum C Programming
    Replies: 5
    Last Post: 07-06-2007, 08:16 AM
  3. Replies: 5
    Last Post: 11-04-2006, 06:39 PM
  4. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  5. Problem with linked list ADT and incomplete structure
    By prawntoast in forum C Programming
    Replies: 1
    Last Post: 04-30-2005, 01:29 AM