When I'm running the following C program for linked list creation in gcc compiler in ubuntu 13.04, I'm getting a message of : Segmentation fault (core dumped) , after the list elements are input from the user , without proceeding further. Kindly help.
#include<stdio.h>
#include<stdlib.h>
int main()
{
/* creating a singly linked list,displaying its elements and finding the sum and average of its elements and searching a particular element in it */
typedef struct node
{
int info;
struct node *next;
}N;
N *ptr,*start,*prev;
int i,n,x;
ptr=NULL;
start=NULL;
prev=NULL;
printf("Enter the number of list elements: ");
scanf("%d",&n);
prev = (N*)malloc(sizeof(N));
start = (N*)malloc(sizeof(N));
for(i=0;i<n;i++)
{
ptr= (N*)malloc(sizeof(N));
prev->next = ptr;
printf("enter the %dth element\t\n",(i+1));
scanf("%d",&x);
ptr->info = x;
if(start==NULL)
{
start=ptr;
prev=ptr;
ptr->next = NULL;
}
else
{
prev=ptr;
}
} /* linked list created consisting of n nodes */
/* finding sum and average*/
int sum=0;
float avg;
ptr=start;
for(i=0;i<n;i++)
{
sum =sum + ptr->info;
ptr = ptr->next;
}
avg = (float)sum/n; /* summing and averaging completed */
/* displaying data */
ptr=start;
printf("\n The list elements are : ");
while(ptr != NULL)
printf("%d\t",ptr->info);
printf("\n");
printf("The sum of list elements is: %d",sum);
printf("The average of list elements is: %f",avg);
return 0;
}
Looks like you meant to do
start = NULL;
prev = NULL;
at the beginning, and also correct -
prev->next = ptr;
to
if (prev != NULL)
prev->next = ptr;
or move it to the else section (before prev = ptr).
This way, the first iteration would make start point to the first element, and the next ones would make the prev element point to the current ptr.
By the way, some linked lists hold a dummy "anchor" element for simpler maintenance, but in your case I see you expect the data to appear from the first element already.
when I strip your code I come to this Seltsamkeit:
start = (N*)malloc(sizeof(N));
for(i=0;i<n;i++) {
if(start==NULL)
start can never be NULL in this context
i normally use "head" and "next" for the pointer to the working memory, and "list" as a running pointer to the last element of the list for the really allocated memory-linked-list. the metacode is:
list = NULL;
head = NULL;
for (i = 0; i < n; i++) {
next = malloc();
if (head == NULL) {
head = next; // setting the first haed;
} else {
list->next = next; // attaching to the end
}
list = next; // pointing to the last element
}
Related
I am unsure why the code below does not execute up to the while loop. It only gives this output:enter image description here
The desired output of this program is that the largest node of the linked list is taken, multiplied by 0.8, and then printed as an output.
Code:
struct Process{
int burst_time;
struct Process* next;
};
int main()
{
int i;
struct Process* head = NULL, *temp = NULL;
struct Process* current = head; // Reset the pointer
int proc_count, time_quantum, total_time;
// BTmax
int max = 0;
printf("How many processes?: ");
scanf("%d",&proc_count);
for(i = 0; i < proc_count; i++)
{
temp = malloc(sizeof(struct Process));
printf("\nEnter burst time of process %d: ", i + 1);
scanf("%d", &temp -> burst_time);
temp->next=NULL;
if(head==NULL)
{
head=temp;
current=head;
}
else
{
current->next=temp;
current=temp;
}
}
current = head;
// BTmax * 0.8
while(current != NULL)
{
if (head -> burst_time > max)
{
max = head->burst_time;
}
head = head->next;
}
time_quantum = max * 0.8;
printf("\nTime Quantum is: %d", time_quantum);
Also, inside while loop you are iterating head variable but in condition you are checking current != NULL
From the way you wrote your while loop (iterating via head=head->next) you are apparently trying to do these two things at the same time:
Scan the list for its largest element
Remove/deallocate each element after it has been considered
Although head=head->next does remove each element from the list, it neglects to deallocate (causing memory to leak).
This loop correctly does both the scanning and the removal/deallocation:
while (head != NULL)
{
if (head->burst_time > max)
{
max = head->burst_time;
}
temp = head;
head = head->next;
free(temp);
}
(Notice that the while condition should be testing head, not testing current. Thus, there is no need to initialize current=head prior to the loop.)
You'll want to change the final while loop. You're checking to make sure current isnt NULL but you're iterating with head. If you still need access to the data, changing the final while loop to this should work :
while(current != NULL) {
if (current->burst_time > max) max = current->burst_time;
current = current->next;
}
Finally, maybe you already have in your actual program, but you need to free() any memory allocated with malloc()
So if you're done with the list at that point you can change the final while loop to :
while(head != NULL) {
if (head->burst_time > max) max = head->burst_time;
temp = head;
head = head->next;
free(temp);
}
I'm missing with linked-list and trying to make a function which gonna take of all the odd numbers out of the link and make a new linked-list with them.
The point is that I dont understand how to update the original list by pointer to the function, actually what I made so far is making a new list with the odd numbers but I dont really understand how to "delete" them from the original list and link all the rest togther, then send it back to the main.
Node *build_odd_list(Node *oldlst, Node *newlst) {
Node *temp, *curheadNew;
temp = (Node*)malloc(sizeof(Node));
if (oldlst->value % 2 != 0) {
temp->next = NULL;
temp->value = oldlst->value;
newlst = temp;
curheadNew = newlst;
oldlst = oldlst->next;
printf("Passed %d\n", curheadNew->value);
}
else {
oldlst = oldlst->next;
}
while (oldlst) {
if (oldlst->value % 2 != 0) {
temp = (Node*)malloc(sizeof(Node));
temp->value = oldlst->value;
temp->next = NULL;
curheadNew->next = temp;
curheadNew = curheadNew->next;
oldlst = oldlst->next;
printf("Passed %d\n", curheadNew->value);
}
else {
oldlst = oldlst->next;
}
}
return newlst;
}
Thanks a lot!
Since you need to return a new list containing the odd numbers, and modify the original list due to removal of the odd numbers, you need to pass two values back to the caller: a pointer to the first element of the updated original list, and a pointer to the first element of the "odd numbers" list.
Since you need to pass the original list to the function anyway, the simplest option for the function is to:
pass a pointer to a pointer to the first element of the original list;
modify the original list via the pointer;
return a pointer to the first element of the "odd numbers" list extracted from the original list.
There is no need to allocate any new elements for the "odd numbers" list as the odd number elements can be moved from one list to the other.
It is worth learning the "pointer to a pointer" trick as it is a common way of manipulating list pointers.
Here is an example program to illustrate the above method. Pay particular attention to the extract_odd_list() function and the call to that function from main().
#include <stdio.h>
#include <stdlib.h>
typedef struct _Node {
int value;
struct _Node *next;
} Node;
/* Move odd numbers in *list to returned list. */
Node *extract_odd_list(Node **list) {
Node *oddstart = NULL; /* start of returned list */
Node **oddend = &oddstart; /* pointer to final link of returned list */
while (*list) {
if ((*list)->value % 2 != 0) {
/* Current element of original *list is odd. */
/* Move original *list element to end of returned list. */
*oddend = *list;
/* Bypass moved element in original list. */
*list = (*list)->next;
/* Update pointer to final link of returned list. */
oddend = &(*oddend)->next;
}
else {
/* Current element of original *list is even. */
/* Skip to next element of original *list. */
list = &(*list)->next;
}
}
/* Terminate the returned list. */
*oddend = NULL;
/* And return it. */
return oddstart;
}
void *printlist(Node *list) {
while (list) {
printf(" %d", list->value);
list = list->next;
}
}
int main(void) {
int i;
Node *list = NULL;
Node *end = NULL;
Node *oddlist;
Node *temp;
/* Construct a list containing odd and even numbers. */
for (i = 1; i <= 10; i++) {
temp = malloc(sizeof(*temp));
temp->value = i;
if (end == NULL) {
list = temp;
}
else {
end->next = temp;
}
end = temp;
}
end->next = NULL;
printf("Original list:");
printlist(list);
printf("\n");
/* Move the "odd number" elements from the original list to a new list. */
oddlist = extract_odd_list(&list);
printf("Updated list:");
printlist(list);
printf("\n");
printf("Odd list:");
printlist(oddlist);
printf("\n");
return 0;
}
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'm printing a linked list after each addition to it. The problem is that it only prints the most recently added node. The user is supposed to enter a string which is used to make a node and then that node is added to the list. Here is the code:
int main() {
char userChoice = printMenu();
int setNumber;
while (userChoice != 'q') {
printf("set: ");
scanf("%d", &setNumber);
Node **nodeArray;
nodeArray = malloc(10 * sizeof(Node *));
int i;
for (i = 0; i < 10; i++) {
nodeArray[i] = malloc(sizeof(Node));
}
if (userChoice == 'a')
add(&nodeArray, setNumber);
else
printf("Please enter a valid menu option.");
//printf("%s\n", (nodeArray[setNumber]->next)->data);
userChoice = printMenu();
}
void add(Node ***nodeArray, int setNumber) {
char userString[5];
printf("Please enter some data: ");
scanf("%s", userString);
Node *head = *nodeArray[setNumber]; /* head pointer to first element of array (dummy) */
Node *newNode = malloc(sizeof(Node)); /* new node to be added to array */
strncpy(newNode->data, userString, sizeof(newNode->data)); /* copies string entered by the user to data field of new node */
newNode->next = NULL; /* initializes next field of new node to NULL */
while (head->next)
head = head->next; /* points head to next element in list */
head->next = newNode; /* adds element to list */
head = *nodeArray[setNumber]; /* points head back to start of list */
Node *tmp = head;
printf("List is: ");
while (tmp->next) {
printf("%s", tmp->data);
tmp = tmp->next;
}
}
Just as an example, when I enter "one", it prints out "one". Then when I add "two" it only prints out two instead of printing out "one two". What am I doing wrong?
This *nodeArray[setNumber] means *(nodeArray[setNumber]) but you seem to mean (*nodeArray)[setNumber]. Or better, don't pass &nodeArray to add(), just pass nodeArray. So:
add(nodeArray, setNumber);
...
void add(Node **nodeArray, int setNumber) {
...
Node *head = nodeArray[setNumber];
The problem is that a new block of memory is being created every time you enter into the loop. Cut and paste the code that creates the array outside of the loop and everything should work fine.
I am trying to create an (ordered) linked list of (ordered) linked lists. The list-of-list links are carried by the first nodes of its member lists. I am trying to achieve this via the following code, but my program crashes right after I try to insert the second node into the list of lists.
Here's a schematic of the data structure I am trying to construct:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node{
int number;
struct node*next;
struct node*lsnext;
};
typedef struct node Node;
Node* insertValue(Node * list, int value);
void display(Node*);
Node* insertArr(Node * list, int value);
int main()
{
Node *globalList = NULL, *lists,*start,*save;
int nbrOfLists, listNo, nbrOfVal, valNo, val;
printf("\n Enter the number of lists:");
scanf("%d", &nbrOfLists);
if(nbrOfLists < 0)
return -1;
for(listNo = 0; listNo < nbrOfLists; listNo++)
{
printf("\n\n Enter the number of inputs to the list %d: \n ",listNo+1);
scanf("%d", &nbrOfVal);
lists = NULL;
for(valNo = 0; valNo < nbrOfVal; valNo++)
{
printf("Enter node value %d:", valNo+1);
scanf("%d", &val);
// Here we insert the value in both lists
lists= insertValue(lists, val);
globalList = insertValue(globalList, val);
}
start=lists;
if(listNo==0){
save=start;
}
start=start->lsnext;
printf("\n The list %d is: ",listNo+1);
display(lists);
}
printf("\n\n The final list is: ");
display(globalList);
printf("The first list is");
display(save);
printf("The second list is");
display(save->lsnext); // CRASHES HERE
return 0;
}
Node* insertValue(Node * list, int value)
{
Node *newNode, *m;
newNode = malloc(sizeof(Node));
newNode->number=value;
if(list == NULL)
{
newNode->next=NULL;
return newNode;
}
if(value < list->number)
{
newNode->next = list;
return newNode;
}
m = list;
while(m->next)
{
if(value < m->next->number)
break;
m = m->next;
}
newNode->next = m->next;
m->next = newNode;
return list;
}
void display(Node*nodex){
while(nodex)
{
printf("%d ->",nodex->number);
nodex=nodex->next;
}
}
What is causing my error?
Your insertArr() function is wrong. Even its signature is wrong. Instead of linking together the first nodes of existing lists, it creates a perpendicular list of separate nodes. Note in particular that it accepts a value where it needs instead to accept the head node of a list.
Moreover, even the circumstances under which you call that function are wrong. You seem to try to link the initial head nodes of each list, but the head node may change as you add values. You must wait until you have a full list before you know what its final head node is; only then can you link that list into your list of lists.
Edit: I had first asserted that your problem was failure to initialize the lsnext members of your nodes. That would be correct if your insertArr() function were actually accepting nodes created by insertValue() as its second argument, as it should, but it is not correct for the code presented. The actual problem is a consequence of the issue described in my first paragraph, that insertArr() creates a separate list of separate nodes. In particular, those separate nodes do not have their next pointers initialized.