Structures inside linked lists in C - c

I'm learning how to implement linked lists in C. I understand the basics of normal linked lists, how to add values, how to print them etc. but I've been wondering - is it possible to add other structure as a value in linked list? What I mean is:
typedef struct personal_info {
char *name;
char *surname;
int phone_number;
} Info;
typedef struct llist {
Info *info;
struct llist *next;
} List;
And when I do this, how do I access the values of the Info structure?
List *l;
l = malloc(sizeof(List));
l->info->name = 'name';
l->info->surname = 'surname';
l->info->phone_number = 1234567890;
The code crashes, so I'm definitely doing something wrong. Could you give me some tips how to achieve that?

You also need to allocate memory for the info struct:
l = malloc(sizeof(List));
l->info = malloc(sizeof(Info));
l->info->name = "name";
l->info->surname = "surname";
l->info->phone_number = 1234567890;

List *l;
l = malloc(sizeof(List));
l->info = malloc(sizeof(Info));
You have to malloc memory for the struct as well
Also remember that if you're implementing any functions that remove nodes from the list, you need to free that struct before you free the node.

Related

Allocating memory for nested linked list + using scanf

I'm struggling with allocating a memory for my linked list which is embedded in it's parent linked list - nested structure.
Structure declaration:
typedef struct parent
{
int x;
struct embed
{
int y;
int l;
struct embed *next;
}EMBED;
struct parent *next;
}PARENT;
Allocating memory for parent list:
PARENT *head = NULL;
PARENT *temp = (PARENT*)malloc(sizeof(PARENT));
What can't I figure out is how can I connect to that embedded list for allocating. Any ideas?
Also when we get to allocating memory and getting connection to that embedded list, I want to use a scanf function to store some data into that list but I do not know the connection declaration. How does it work, can someone explain?
Just so you know what am I working on, it is a school project for searching in a tree - starting from point A, finish at point B when inputs are numbers and in between them is a distance variable. So basically I want to find the shortest way (less calculations = short execution time) from getting to point B.
Thanks for suggestions.
Once the structure is properly defined, you can allocate an embedded list element like so:
temp->EMBED.next = malloc(sizeof(struct embed));
You don't need that inner typedef inside the struct definition. In fact, my GCC doesn't like it. This works:
typedef struct parent
{
int x;
struct embed
{
int y;
int l;
struct embed *next;
} embed;
struct parent *next;
} PARENT;
With this, you can allocate and fill a list with something like this:
PARENT p;
/* build up a list */
p.embed.next = NULL;
for (i = 0; i < 5; i++) {
struct embed *new = malloc(sizeof *new);
new->next = p.embed.next;
printf("enter a number:\n");
scanf("%d", &new->y);
p.embed.next = new;
}

How to make a new instance of a struct in c

I am new to C and thus still working on learning the language. I have created a linked list struct in a header file and I am trying to create a new instance of this struct. I know in java you can use the new operator but how would I mimic this behavior in c? Traditionally I would think of the following:
code within linked.h
typedef struct linked_list{
//assuming node type is implemented
node *next_node;
}
code within linked.c
linked_list *link = NULL;
link = malloc(number_nodes);
link->node_value = 10;
Any help you can provide is extremely helpful to me as I am having trouble understanding this concept.
malloc needs to know how many bytes to allocate, so you need to multiply the number of nodes by the size of one node in bytes.
Change:
link = malloc(number_nodes);
to
link = malloc(number_nodes * sizeof(*link));
Or if you just want a single struct:
link = malloc(sizeof(*link));
If you want enough memory for one struct linked_list, all you have to do is
struct linked_list * mylist = malloc(sizeof(*mylist));
mylist -> next_node = NULL;
For each node you want to add, you have to do
struct node * mynewnode = malloc(sizeof(*mynewnode));
mynewnode -> ... = ...; // fill in the data you have
mynewnode -> next_node = mylist -> next_node;
mylist -> next_node = mynewnode;
You should maintain the memory of all nodes independent on each other so you can free them.

Adding items to an empty linked list C

For a project i am expected to create an empty linked list in one function, and then use that linked list in another function to add items into it. At the moment this is my code for the empty linked list:
typedef struct node_t {
int value;
int priority;
struct node_t *next;
}node;
typedef struct priorty_linked_list {
struct name *head;
int current_size;
int max_size;
}priority_list;
typedef node *Node;
typedef priority_list *List;
Our instructor gave us the above code, so there shouldnt be anything wrong with it. Next i started with the function create:
void create(int max_terms) {
node *head = NULL;
node *next = NULL;
List *current_size = 0;
List *max_size = max_terms;
max_size = (List*)malloc(sizeof(List));
printf("The maximum size for the list is %d",max_terms);
}
I'm assuming that the next function requires me to use a return function from the create function, but im not sure how. The add function should take the queue created above as a parameter, and not work if i havent created a queue before due to memory allocation.
Any tips or advice on my above code would be greatly appreciated!
Thanks :)
I'm going to guess that in the definition of priorty_linked_list, you wanted to write:
struct node *head;
instead of:
struct name *head;
This site has a great explanation and decent implementation that can be used for reference. There are thousands of examples in the Web very similar to what you have to implement. Don't be afraid to Google it.

A Hashset that holds a generic linked list that holds a generic linked list

This is my data structure for an Assignment I'm doing in class. I'm supposed to implement a a hash set that holds a string of linked lists. Each of those individual linked lists holds an int. My list is generic, if it works, using (void* data) like this:
typedef struct NodeStruct {
void *data;
struct NodeStruct* next;
struct NodeStruct* prev;
} NodeStruct;
// Rename NodeStruct* as NodePtr
typedef NodeStruct* NodePtr;
typedef struct ListStruct {
int elementType;
NodePtr first;
NodePtr last;
NodePtr current;
} ListStruct;
// ListHndl is just a ListStruct* renamed.
First question: Right now, I"m using memcpy(list->data, data, list->elementType).
I was wondering.. is it okay do just store it directly, like list->data = data?
This is my hash set struct:
typedef struct HashStruct {
int size;
int load;
ListHndl *chain; //An array of Linked Lists.
} HashStruct;
typedef HashStruct* HashHandle
HashHandle new_hashset(int size) {
HashHandle tempHash = malloc (sizeof (HashStruct));
assert (tempHash != NULL);
tempHash->size = size;
tempHash->load = 0;
tempHash->chain = malloc (sizeof (ListHndl) * size);
assert(tempHash->chain != NULL);
for (int i = 0; i < size; i++) {
tempHash->chain[i] = newList(sizeof(char*));
tempHash->chain[i]->data = malloc(sizeof (ListHndl)); // Error here
}
return tempHash;
}
This is the error that I'm getting.
hash.c: In function ‘new_hashset’:
hash.c:28:27: error: dereferencing pointer to incomplete type
tempHash->chain[i]->data = malloc(sizeof (ListHndl));
^
Second question: I'm not sure how I'm supposed to be allocating memory for these linked lists, which is probably why I got this error.
Am I even implementing this data structure correctly? If more information is needed, please let me know. Thank you!
First question: Right now, I"m using memcpy(list->data, data, list->elementType). I was wondering.. is it okay do just store it directly, like list->data = data?
That depends on what 'data' is pointing to. It is quite common to list->data = data when 'data' is pointing to memory allocated from the heap,
Second question: I'm not sure how I'm supposed to be allocating memory for these linked lists, which is probably why I got this error.
For the typedefs outlined in the question, you will need to allocate memory for:
Each new node: newNode=malloc(sizeof(NodeStruct))
Each node payload: newNode->data = malloc(sizeof(int))
Am I even implementing this data structure correctly?
It is difficult to say with the limited code provided. Of course, there are many ways to accomplish the assigned task; including those ways that are easier to understand, as well as those which are specifically tuned for performance.

Reusing existing linked list API implementation

I have in the existing source base, linked list implementation(adding node, insertion, deletion , traversal) for the following structure:
typedef struct tagDirInfo
{
char *pdirName;
struct tagDirInfo *__next;
struct tagDirInfo *__prev;
}DIR_HEADER;
Lets assume that char* pdirName points to the data part
I want to form a wrap up for the data part and reuse the existing APIs and so that, the new linked list structure has the data part as:
typedef struct printJob
{
char labelName[BUF_LEN];
int priStatus;
time_t time_stamp;
}PRINTJOB;
I think if I do something like:
PRINTJOB newJob;
/* Fill in newJob structure */
DIR_HEADER *newNode;
newNode->pdirName = (char*)newJob;
newNode->__next = NULL;
newNode->__prev = NULL;
Doing so, will fill in the linked list structure.
But how can I access labelName data field through pdirName field of the linked list structure?
Do you mean you want do something like :
printf("labelName : %s\n", ((PRINTJOB *)(newNode->pdirName))->labelName);
However, your code have one mistake! To correct it:
Change
newNode->pdirName = (char*)newJob;
to
newNode->pdirName = (char*)&newJob;
You should use templates (if you could use c++).
char* Labelname = ((PRINTJOB*) newNode->pdirName)->labelName;
By the way, "newJob" should be of type PRINTJOB* not PRINTJOB.
A better solution would be following:
typedef struct _LINKED_LIST {
struct _LINKED_LIST *_Next;
struct _LINKED_LIST *_Prev;
} LINKED_LIST;
typedef struct {
LINKED_LIST List;
char labelName[BUF_LEN];
int priStatus;
time_t time_stamp;
} MY_LINKED_LIST_DATA;
MY_LINKED_LIST_DATA* MyData = (MY_LINKED_LIST_DATA*)
malloc(sizeof(MY_LINKED_LIST_DATA));
MyData->List->_Next = NULL;
MyData->List->_Prev = NULL;
Your data always contains linked list specific fields _Next and _Prev.

Resources