Pointer one linked list to another linked list

Go To StackoverFlow.com

0

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;
2012-04-03 22:58
by Learning C
Side note: you can define structures like this: typedef struct users_ { /* whatever */ } users; doing both definition and typedef in one statement. Furthermore, since struct users and users 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
Thanks for the tip - Learning C 2012-04-03 23:20


1

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 :)

2012-04-03 23:05
by inspector-g
I had 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
You have another error in the program. If the program enters the 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
Should I change that to if( head_users == NULL){} - Learning C 2012-04-03 23:12
Also, as Shahbaz pointed out, you are not initializing your pointer variables. You should always initialize variables to some "safe" default; in the case of pointers, use NULL (i.e. users* head_users = NULL - inspector-g 2012-04-03 23:14
I did initialized it to NULL, just forgot to copy it over to the question - Learning C 2012-04-03 23:15
No, sorry, I wasn't clear. In the 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
@LearningC I guess you wanted to create playlist if 'user' list is already there. So just add the condition which I edited in my post - P.P. 2012-04-03 23:18


2

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.

2012-04-03 23:09
by Shahbaz
I did initialized but forgot to copy it over on the question - Learning C 2012-04-03 23:17
Then if there is anything else in the code that is missing, put them here because the error could be there - Shahbaz 2012-04-03 23:18