The code doesn't work until I dynamically allocate the memory for pointer C in merge_List function.
If I uncomment list c = (list)malloc(sizeof(Node)); and comment
list c;, the code works.
I don't know why. Can anyone explain to me?
The code is very straightforward, so not much comment.
Thank you!
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
struct Node *next;
int value;
}Node,*list;
list create_Node()
{
list head = (list)malloc(sizeof(Node));
if(!head) exit(-1);
list tail = head;
int len;
int val;
printf("Please enter the length of the list:\n ");
scanf("%d",&len);
for(int i=0;i<len;i++)
{
list new = (list)malloc(sizeof(Node));
if(!new) exit(-1);
printf("Please enter the value of the node:\n ");
scanf(" %d",&val);
new->value=val;
tail->next= new;
tail =new;
}
return head;
}
list merge_list(list a, list b)
{
if(a==NULL||b==NULL) exit(-1);
//list c = (list)malloc(sizeof(Node));
list c;
list d = c;
while(a&&b)
{
if(a->value<=b->value)
{
c->next=a;
c=a;
a=a->next;
}
else
{
c->next = b;
c=b;
b=b->next;
}
}
c->next = a?a:b;
return d;
}
int main() {
list l = create_Node();
l=l->next;
list j = create_Node();
j=j->next;
list n =merge_List(l,j);
n=n->next;
while(n)
{
printf("%d\n",n->value);
n=n->next;
}
return 0;
}
It took a bit of inspection, but this is the struct's type is
list {aka struct Node *}
According to the compiler. In other words, list is a pointer, and calling malloc will allocate memory for the pointer.
You did this before in your function create_Node(), on the line right after
list head = (list)malloc(sizeof(Node));
If you don't do this, you're performing actions on an uninitialized pointer, which is undefined behavior and shouldn't work since you don't clearly have a spot in memory you're using.
What malloc specifically does in this context, will allocate the sizeof a Node's bytes, and return a void pointer, which you cast to a list (or Node *). List will no longer be uninitialized and no longer has undefined behaviour, which is why it works.
Related
This is a code from my programming with C course that prints a list, using ADT structs.
typedef struct list{
int data;
struct list *next;
}list;
int is_empty(const list *l){
return(l==NULL);
}
void print_list(list *h, char *title){
printf("%s\n", title);
while(h!=NULL){
printf("%d :", h -> data);
h = h -> next;
}
}
int main()
{
list list_of_int;
list* head = NULL;
head = malloc(sizeof(list));
printf("size of the list = %lu\n",sizeof(list)); //this has to be an unsigned long
head -> data = 5;
head -> next = NULL;
print_list(head,"single element list");
printf("\n\n");
return 0;
}
My question is, how we used malloc() and the memory it created to create the list pointer head?
The purpose of malloc is "making" legal space and providing a pointer to it.
The following lines in your code make sure that legal space contains values which make a node.
This might seem short, but that's it.
(And I think you confirmed that you now understand. Otherwise I would consider it too short to be polite myself.)
Merge the two linked list in C language.
I tried to merge the two sorted double linked list. When I ran my code with different inputs, sometime the code just crushed with EXC_BAD_ACCESS error. I can't figure out why, the code seemed perfect for me and I use the similar way to merge two single linked list, it worked.
Can someone explain? Thanks!
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
struct Node* prior;
struct Node* next;
int value;
}Node,*list;
list create_list()
{
list head = (list)malloc(sizeof(Node));
if(!head) exit(-1);
list tail;
tail=head;
printf("Please enter the length of double linked list:\n");
int len;
scanf("%d",&len);
for(int i=0;i<len;i++)
{
list new = (list)malloc(sizeof(Node));
printf("Please enter the value of node:\n");
int val;
scanf("%d",&val);
new->value=val;
tail->next = new;
new->prior=tail;
tail=new;
}
return head;
}
list merge_list(list a, list b)
{
if(a==NULL||b==NULL) exit(-1);
list p=(list)malloc(sizeof(Node));
list l=p;
while(a&&b)
{
if(a->value<=b->value)
{
p->next = a;
a->prior=p;
p=a;
a=a->next;
}
else
{
p->next = b;
b->prior=p;
p=b;
b=b->next;
}
}
if(a!=NULL)
{
p->next=a;
a->prior=p;
}
if(b!=NULL)
{
p->next=b;
b->prior=p;
}
return l;
}
int main() {
list l = create_list();
l=l->next;
list m = create_list();
m=m->next;
list n =merge_list(l,m);
n=n->next;
while(n)
{
printf("%d\n",n->value);
n=n->next;
}
return 0;
}
The problem is that in create_list you do not initialize new->next with NULL.
From this error it makes no sense in merge_list to compare pointers with NULL.
The most important bug (i.e. no initialization of new->next) has already been addressed by the answer from #alinsoar.
However, there are other bugs in your code that a) cause memory leaks and b) cause the linked list to be incorrect.
In main you have:
list l = create_list();
l=l->next; // Why ......
Why do you "throw away" the first element like that? That's a memory leak! And further it means that l->prio is not NULL as it should be!
I know it's because your create_list inserted a phony node in the start. But don't just fix it by throwing the node away. Fix the function instead.
Do something like this:
list create_list()
{
list head = NULL; // Do not use malloc here - just assign NULL
list tail = NULL;
printf("Please enter the length of double linked list:\n");
int len;
scanf("%d",&len);
for(int i=0;i<len;i++)
{
list new = malloc(sizeof(Node)); // do not cast malloc
new->next = NULL; // set the next pointer
printf("Please enter the value of node:\n");
int val;
scanf("%d",&val);
new->value=val;
// Add the node to the end
new->prior=tail;
if (tail)
{
tail->next = new;
}
else
{
// First element so update head
head = new;
}
tail=new;
}
return head;
}
With this code you don't get an extra element in the start and you can delete the code l=l->next; in main. Similar changes applies to merge_list but I'll leave that to you as an exercise.
In the end your mainshould only be:
int main() {
list l = create_list();
list m = create_list();
list n =merge_list(l,m);
while(n) {
printf("%d\n",n->value);
n=n->next;
}
return 0;
}
I am trying basic creation of linked list using C. I have written the following code which is working up until first node but fails eventually on second one. I think the issue is where I am trying to display the node values in list separated by arrow(->). I think my logic is right but please correct me. Thanks in advance
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node
{
int number;
struct node *next;
};
typedef struct node NODE;
NODE *node1, *node2, *start, *save;
int main()
{
node1 = (NODE *)malloc(sizeof(NODE));
int i = 0;
start = NULL;
for(i = 0; i < 3; i++)
{
int inf;
printf("Enter node value:");
scanf("%d", &inf);
node1->number = inf;
node1->next = NULL;
if(start == NULL)
{
start = node1;
save = node1;
}
else
{
// save=start;
// start=node1;
// node1->next=save;
node1->next = start;
start = node1;
}
while(node1 != NULL)
{
printf("%d ->",node1->number);
node1 = node1->next;
}
}
return 0;
}
The issues are
How you're allocating your nodes for insertion (i.e. save for one, you're not).
How they're placed in the list once you fix the above.
Don't cast malloc in C programs (read here for why).
Fail to check the success of your scanf invoke.
Fail to check the success of your malloc invoke
Before you get discouraged, things you did correctly:
Did not mask a node pointer in a typedef
Properly included a MCVE for review
Prospected the things you may be doing wrong.
A very simple example of iterating three values into a linked list would look something like this:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int number;
struct node *next;
};
typedef struct node NODE;
int main()
{
NODE *head = NULL, *p;
int i = 0;
for(i = 0; i < 3; i++)
{
int inf;
printf("Enter node value:");
if (scanf("%d", &inf) == 1)
{
p = malloc(sizeof *p);
if (p != NULL)
{
p->number = inf;
p->next = head;
head = p;
}
else
{
perror("Failed to allocate new node");
return EXIT_FAILURE;
}
}
else
{
// failed to read data. break
break;
}
// report current linked list
printf("%d", p->number);
for (p=p->next; p; p = p->next)
printf(" -> %d", p->number);
fputc('\n', stdout);
}
// cleanup the linked list
while (head)
{
p = head;
head = head->next;
free(p);
}
head = NULL;
return 0;
}
Input
The values 1 2 3 are input upon being prompted:
Output
Enter node value:1
1
Enter node value:2
2 -> 1
Enter node value:3
3 -> 2 -> 1
Best of luck.
You should use malloc() inside for loop.
Since it is outside, same memory is being used.
As said by Vamsi, you should use malloc to put the nodes on the heap. You also generally shouldn't cast the output of malloc, it isn't needed. And then you could play around with making a doubly-linked list, where you also have a prev pointer inside your struct.
here's my code in C for making of linked list. Its giving runtime error after the while loop gets executed for one time. Plz help me in correcting my code. (totally confused that where's the error.) I am making a head node first and then adding child nodes to it.
#include <stdio.h>
#include <stdlib.h>
typedef struct node nd;
typedef nd *link;
struct node{
int data;
link next;
};
typedef struct {
int size;
link head;
}list;
void create(link temp)
{
link new;
new=(link)malloc(sizeof(nd));
printf("enter data: ");
scanf("%d",new->data);
temp->next=new;
temp=temp->next;
}
list createlist()
{
list sl;
sl.size=0;
sl.head=0;
return sl;
}
int main()
{
list sl;
sl=createlist();
link temp;
temp=sl.head;
char c;
while (1)
{
printf("Add node?: ");
scanf(" %c",&c);
if (c=='y')
{
create(temp);
sl.size++;
}
else
break;
}
return 0;
}
your createlist() function is returning a reference to a local variable that goes out of scope after it returns. You should instead return a heap based value:
list* createlist() {
list* sl = (list*)malloc(sizeof(list));
sl->size=0;
sl->head=0;
return sl;
}
Initially temp points to NULL. temp = sl.head;
In create(temp) temp->next = new;
You are dereferencing a NULL, address 0x0. I get a segmentation fault when I do that.
Need to change the algorithm.
A debugger shows this problem immediately.
You could use a pointer to pointer for temp. It would be easier to read if you didn't use a typedef for a pointer to node. I haven't tested this, but it should be close:
nd ** create(nd **temp)
{
nd *new;
new=(nd *)malloc(sizeof(nd)); /* this cast shouldn't be needed */
printf("enter data: ");
scanf("%d",&(new->data));
new->next = NULL;
*temp = new;
return &(new->next);
}
/* ... */
int main()
{
nd **temp;
temp = &(sl.head);
/* ... */
temp = create(temp);
/* ... */
}
I am trying to implement the Linked List data structure for my college course, but on executing the code the following line produces an EXC_BAD_ACCESS(code=1, address=0x8) error.
temp->next = (ptrtonode) malloc(sizeof(struct node));
Following is the code in its entirety.
#include <stdio.h>
#include <stdlib.h>
typedef struct node *ptrtonode;
typedef ptrtonode header;
struct node
{
int data;
ptrtonode next;
};
ptrtonode create(int n)
{
int i;
header temphead = NULL;
ptrtonode temp = temphead;
for(i=0;i<n;i++)
{
temp->next = (ptrtonode) malloc(sizeof(struct node));
printf("Enter data for node %d: ", i+1);
scanf("%d", &temp->next->data);
temp = temp->next;
}
temp->next = NULL;
return temphead;
}
int main(int argc, const char * argv[])
{
header head;
int n;
printf("How many nodes do you wish to create?");
scanf("%d", &n);
head = create(n);
}
Any help would be appreciated.
Thanks all!
On first iteration of the for loop inside the create() function temp is NULL, which is then dereferenced causing the failure (not malloc() causing the failure). You will need to restructure the code slightly to prevent dereferencing a NULL pointer.
Other points:
casting the return value of malloc() is not required.
check the result of scanf() to ensure n was assigned a valid integer (and confirm that the int is positive):
/* scanf() returns the number of assignments made,
which in this case should be 1. */
if (1 == scanf("%d", &n) && n > 0)
{
/* 'n' assigned a sensible value. */
}