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;
}
}
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).
users_pointer
is pointing to it. I also pass this to bothadd_playlist()
andprint_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