'debug an array of linked lists in c
I'm having a trouble in my project, at first I made one linked list and it worked properly but then I had to edit it and make it an array of linked list, but it just stores in a wrong way I guess, here is my code, what's wrong with it?
#include <stdio.h>
#include <stdlib.h>
struct node
{
int coeff;
int power;
struct node* Next;
};
void Insert(int X,int Y, struct node* L, struct node* P)
{
struct node* temp;
temp = (struct node*)malloc(sizeof(struct node));
temp->coeff = X;
temp->power = Y;
temp->Next = P->Next;
P->Next = temp;
}
void PrintList(struct node* L)
{
struct node* P = L;
printf("%d %d ",P->coeff,P->power);
printf("\n");
P=P->Next;
}
int main()
{
struct node* head[3] ;
for(int q =0 ; q!= 3 ; q++)
{
head[q] = malloc(sizeof(struct node));
}
Insert(1,2,head[0],&head[0]);
Insert(2,3,head[0],&head[0]);
Insert(1,2,head[1],&head[1]);
Insert(2,2,head[1],&head[1]);
for(int i=0 ;i!=3;i++){
PrintList(head[i]);
}
return 0;
}
Solution 1:[1]
In a LinkedList there is only 1 head. You have allocated 3 different heads and are trying to add nodes to these heads. So the following answer assumes you intend to have 3 different LinkedLists with each list's head in an array.
The memory from malloc()
in this line
head[q] = malloc(sizeof(struct node));
was uninitialized. Using calloc()
appeared more prudent here. So,
head[q] = calloc(sizeof(struct node), 1); //Initialize everything to 0
Next, one of the arguments in your Insert()
was redundant and also didn't go with your calling code. It is of the signature
void Insert(int ,int , struct node* , struct node*)
but you're invoking it with
void Insert(int ,int , struct node* , struct node**)
Dropping the last argument should be fine, I guess, in this case since you aren't modifying the incoming struct node*
pointer but its contents instead. In case you were changing the struct node*
to point to something else within the Insert()
function (e.g. P = temp;
etc.), then passing in a struct node**
would have more meaning. So, changing your code to
void Insert(int X,int Y, struct node* P)
{
struct node* temp;
temp = (struct node*)malloc(sizeof(struct node));
temp->coeff = X;
temp->power = Y;
temp->Next = P->Next;
P->Next = temp;
}
And the calling code to
Insert(2,3,head[0]);
Insert(1,2,head[0]);
Insert(1,2,head[1]);
Insert(2,2,head[1]);
Next, changing your PrintList
to actually traverse the LinkedList:
void PrintList(struct node* L)
{
struct node* P = L;
while(P) {
printf("%d %d\n",P->coeff,P->power);
P=P->Next;
}
}
Apart from that, I just added some logging to better clarify the LinkedList being printed.
for(int i=0 ;i!=3;i++){
printf("Printing list %d:\n", i);
PrintList(head[i]);
printf("*****\n");
}
This gives the output:
Printing list 0:
0 0
1 2
2 3
*****
Printing list 1:
0 0
2 2
1 2
*****
Printing list 2:
0 0
*****
Obviously, all the head
of the LinkedLists are 0 initialized and hence show up as 0 0
. They could be initialized as deemed fit, or could be dropped from the PrintList()
function altogether, depending on your program's expectations.
Solution 2:[2]
When working on a C project you should always enable compiler warnings. If you do the compiler will issue a warning like
warning: passing argument 4 of ‘Insert’ from incompatible pointer type [-Wincompatible-pointer-types]
This is just the first problem in your code. You also have uninitialized fields in the nodes you allocate in the main function.
Instead of having a function which modifies the list, it is more flexible to define a function which adds a new node to a list and returns the new list. Below is an alternative approach which also uses convenience macro functions for allocating memory and calculating the length of an array. The code also hides the pointer behind a type definition and defines a function which frees a list.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN(array) ((int) (sizeof (array) / sizeof (array)[0]))
#define NEW_ARRAY(pointer, length) \
{ \
(pointer) = malloc(((size_t) length) * sizeof (pointer)[0]); \
if ((pointer) == NULL) { \
fprintf(stderr, "Allocating memory with malloc failed: %s\n", strerror(errno)); \
exit(EXIT_FAILURE); \
} \
}
#define NEW(pointer) NEW_ARRAY((pointer), 1)
typedef struct node *List;
struct node {
int coeff;
int power;
struct node *next;
};
List NewList(int coeff, int power, List next)
{
List node;
NEW(node);
node->coeff = coeff;
node->power = power;
node->next = next;
return node;
}
void FreeList(List list)
{
if (list != NULL) {
FreeList(list->next);
free(list);
}
}
void PrintList(List list)
{
while (list != NULL) {
printf("%d %d\n", list->coeff, list->power);
list = list->next;
}
}
int main(void)
{
List head[3] ;
head[0] = NewList(1, 2, NewList(2, 3, NULL));
head[1] = NewList(1, 2, NewList(2, 2, NULL));
head[2] = NULL;
for (int i = 0; i < LEN(head); i++) {
PrintList(head[i]);
FreeList(head[i]);
}
return 0;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Zoso |
Solution 2 | August Karlstrom |