Can't figure out the reason for this segmentation fault

Go To StackoverFlow.com

1

I'm stuck and can't figure out why I get a segmentation fault. When I add the first add to the playlist everything is fine. Then when I print the playlist then try to add more to the playlist I get segmentation fault. gdb is reporting the error here if( (curr_playlist -> album) == NULL && (curr_playlist -> track_num) == NULL){. Can anyone help me find the problem? Is the print function modifying the link list?

struct playlist_ {
  int album;
  int track_num;
  struct playlist_ *next;
};
typedef struct playlist_  playlists;

struct users_ {
  int user_ID;
  struct playlist_ *playlist;
  struct users_ *next;
};
typedef struct users_ users;

/*This is how I created the user list*/

fscanf(transaction_file,"%d\n",&account_number);

      /*Checks for empty list, if true creates the first user*/
      if( head_users == NULL){
        p_users = malloc(sizeof(users ));
        p_users -> user_ID = account_number;
        head_users = p_users;
        curr_users = p_users;
        head_users -> next = NULL;
        users_pointer = head_users;

      /*If list is not empty create new user and puts it in front of list*/
      }else{
        p_users = malloc(sizeof(users));
        p_users -> user_ID = account_number;
        curr_users = p_users;
        curr_users -> next = head_users;
        head_users = curr_users;
        users_pointer = head_users;
      }

      /*Create an empty playlist for user and set everything to null, empty playlist*/
        p_playlists = malloc(sizeof(playlists));
        curr_playlists = p_playlists;
        curr_playlists -> album = FALSE;
        curr_playlists -> track_num = FALSE;
        curr_playlists -> next = NULL;
        curr_users -> playlist = p_playlists;

int add_playlist(users *user_pointer,album *all_albums,int user_ID,int album_ID,int track_num){

  playlists *head_playlist,*tail_playlist,*curr_playlist,*p_playlist;
  users *curr_users;

  curr_users = user_pointer;
  while(curr_users){

    /* Find this user in link list */
    if(curr_users -> user_ID == user_ID){
      curr_playlist = curr_users -> playlist;

      /* Check if playlist is empty for this user if so, update the empty list*/
      if( (curr_playlist -> album) == NULL && (curr_playlist -> track_num) == NULL){
        tail_playlist = curr_users -> playlist;
        curr_playlist -> album = album_ID;
        curr_playlist -> track_num = track_num;
        curr_playlist -> next = NULL;

      }else{

        /*Creates a new playlist node with the request album and track number*/
        p_playlist = (playlists *)malloc(sizeof(playlists ));
        p_playlist -> album = album_ID;
        p_playlist -> track_num = track_num;
        p_playlist -> next = NULL;

        /*Traverse Playlist, find the tail node*/
        curr_playlist = curr_users -> playlist;
        while(curr_playlist ){
          tail_playlist = curr_playlist;
          curr_playlist = curr_playlist -> next;
        }

        /* Adds the new playlist at the end */
          tail_playlist -> next = p_playlist;
      }

    }
    curr_users = curr_users -> next;
  }
  /*Updates the playlist hits for each new playlist node*/
  *all_albums[album_ID].playlist_hits[track_num] = *all_albums[album_ID].playlist_hits[track_num] + 1;
}

int print_account(album *all_albums,int account_number,users *user_pointer){
  users *curr_users;
  playlists *curr_playlist;

  int i;
  curr_users = user_pointer;

  /*Check playlist for each user if NULL, playlist is empty*/
  while (curr_users){
    if(curr_users -> user_ID == account_number){

      printf("ACCOUNT %d\n",curr_users->user_ID);
      if(curr_users -> playlist -> album == -100 && curr_users -> playlist -> track_num == -100){
        printf("  EMPTY Playlist\n");

      }else{
        /*Goes through the user playlist and prints out the information*/
        for(curr_playlist = curr_users -> playlist; curr_playlist; curr_playlist = curr_playlist -> next){
          printf("  ALBUM %d:  %s\n",curr_users -> playlist -> album,
                 all_albums[curr_users -> playlist -> album].tracks[curr_users -> playlist -> track_num]);
          curr_users -> playlist = curr_users -> playlist -> next;
        }
      }
    }
      curr_users = curr_users -> next;
  }
}
2012-04-05 23:50
by Learning C


2

It seems likely that part of the problem may be the assumption that curr_users -> playlist has been initialized with a pointer to an "empty" playlist. If it is NULL or has an uninitialized value, then it will result in the segmentation fault when album is checked in the subsequent statement. The code doesn't show how the user list is initially created, so I'm speculating a bit.

If the user list is not initially created with an "empty" playlist entry, then the playlist member should be initialized to NULL and this statement:

     if ( (curr_playlist -> album) == NULL && (curr_playlist -> track_num) == NULL )

Should likely instead be:

if ( curr_playlist == NULL )

And then it should allocate (via malloc) a new playlist similar to the else portion. (Of course, then there is the modularity issue where both the if block and the else block are allocating and initializing the playlist structure).

2012-04-06 00:00
by Mark Wilkins
I just added how I created users. I successfully created a user linked list users_pointer is pointing to it. I also pass this to both add_playlist() and print_account. I run addplaylist(), then printaccount then when I try to run add_playlist again I get the error - Learning C 2012-04-06 00:10
I just saw your update and it got rid of the segmentation fault error. Thank you so much - Learning C 2012-04-06 00:13
@LearningC: I looked at your updates that show the initialization of the user list, and I am not sure that my answer is correct. I was guessing (speculating) that the list did not initially contain the empty playlist element ... but it does. So I'm still a bit puzzled. If that change eliminated the seg fault, then it would indicate the pointer was NULL (or uninitialized). But that is not quite consistent with the new code showing the initialization of the user elements - Mark Wilkins 2012-04-06 00:18
Thanks a lot for the help. I really appreciated it. Spent 4 hours trying to find the bug. It really helps to get a fresh pair of eyes. Thanks again - Learning C 2012-04-06 00:45
Ads