I'm trying to point a pointer in one structure to a node of another structure. I've been stuck on this 10 hours now. Can someone help me fix my code? I'm getting Segmentation fault at curr_users -> playlist = p_playlists;
. Am I pointing it wrong?
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;
int transaction(FILE *transaction_file,album *all_album){
int transaction_id,i;
int album_ID,
account_number,
add_playlist_user,
add_playlist_album,
add_playlist_track;
users *head_users,*curr_users,*p_users,*users_pointer;
playlists *head_playlists,*curr_playlists,*p_playlists,*playlist_pointer;
head_users = NULL;
fscanf(transaction_file,"%d\n",&account_number);
/*Checks for empty list, if true creates the first user*/
if( !(head_users)){
p_users = malloc(sizeof(users ));
p_users -> user_ID = account_number;
head_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*/
p_playlists = malloc(sizeof(playlists *));
curr_playlists = p_playlists;
curr_playlists -> album = 5;
curr_playlists -> track_num = 5;
curr_playlists -> next = NULL;
curr_users -> playlist = p_playlists;
The error message received when I run this code:
Program received signal SIGSEGV, Segmentation fault.
0x00011050 in transaction (transaction_file=0xff3675cc, all_album=0x226b0)
at functions.c:94
94 curr_users -> playlist = p_playlists;
The error seems to be in this line:
p_playlists = malloc(sizeof(playlists *));
You are allocating enough memory for a pointer to a playlist_
structure, not enough memory for an entire playlist_
structure. Change the line to:
p_playlists = malloc(sizeof(playlists));
to allocate enough memory for the playlist_
struct.
EDIT
As indicated in the comments below, you also need to assign something to curr_users
in the else
block. Then, barring any other errors in your program, it should work :)
p_playlists = malloc(sizeof(playlists));
but i changes it to experiment before I posted this question. I changed it back but it is still gives me the same error - Learning C 2012-04-03 23:07
if(!(head_users))
condition, then you never set the curr_users
variable. By calling curr_users->playlist = p_playlists;
you are dereferencing a bad variable (curr_users
). This will cause a seg fault - inspector-g 2012-04-03 23:10
NULL
(i.e. users* head_users = NULL
- inspector-g 2012-04-03 23:14
if(!(head_users))
condition, you need to assign curr_users
to something. I don't know what your program is ultimately supposed to do, but it looks like doing curr_users = head_users;
is the right thing (similar to how you're doing curr_users = p_users;
in the else
condition) - inspector-g 2012-04-03 23:15
People already gave the answer, but I thought I would make it more complete with a suggestion:
To minimize the confusion, to make sure you get it right, and to minimize maintenance effort in case of certain changes, always use malloc
like this:
type *pointer = malloc(count * sizeof(*pointer));
Note that in this case, the type
of pointer
is only mentioned once. If it changes, you don't need to touch the rest of the code. Also, sizeof(*pointer)
always correctly shows the size of elements that can exist in pointer
.
Now to get back to your code, have you noticed that you have the following local variables:
users *head_users, *curr_users, *p_users, *users_pointer;
that are not initialized, and you are checking
if( !(head_users))
? Since your comment says if list is empty, create the first user
, I am guessing what you need is to make head_users
global, or pass it to transaction
and initialize it to NULL
at program start.
typedef struct users_ { /* whatever */ } users;
doing both definition and typedef in one statement. Furthermore, sincestruct users
andusers
are two different things, you can even drop the underscore:typedef struct users { /* */ } users;
. Even further more, you can even drop the struct name:typedef struct { /* */ } users;
although I don't recommend this last one - Shahbaz 2012-04-03 23:17