Simple C trie program goes wrong (segmentation fault) [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
In order to understand tries I am creating this very simple C program that takes from user 10 nums from 0 to 9 as children of the trie. The final step is to print this nums with the function print, but I am getting a segmentation fault:
#include <stdio.h>
#include <stdlib.h>
typedef struct list
{
int data;
struct list *ar[10];
} list;
void insert(list *head);
void print(list *head);
int main(void)
{
printf("hello\n");
list *root = malloc(sizeof(list));
insert(root);
print(root);
}
void insert(list *head)
{
int a, i;
if (head == NULL) {
return;
}
for (i = 0; i < 10; i++) {
printf("Give Num 0-9\n");
scanf("%i", &a);
head->ar[a] = malloc(sizeof(head));
head = head->ar[a];
head->data = a;
}
}
void print(list *head)
{
if (head == NULL) {
return;
}
while (head != NULL) {
for (int i = 1; i < 10; i++) {
if (head->ar[i] != NULL) {
printf("%i", i);
head = head->ar[i];
break;
}
}
}
printf("\n");
}

There are several issues with your code:
The first mention of malloc doesn't actually initialize the memory (the ar field). You should initialize it properly
list *root = malloc(sizeof(list));
Is missing initialization, e.g.
root->data = 0;
for (size_t ii = 0; ii < 10; ii++) {
root->ar[ii] = NULL;
}
When you are actually gathering input, you allocate only enough memory for the pointer, not for the actual list itself.
head->ar[a] = malloc(sizeof(head));
should be initialized as above (head = malloc(sizeof(list)); for (size_t ...
There seems to be an infinite loop when actually running your program (after correcting all these issues).
EDIT: Remove calloc...

Related

Previous question about how a linked list and a stack works [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Yesterday I saw this question from a new contributor about how a linked list works in C. Since my answer might help someone I decided to re-post the question and provide my code.
First I modified the OP code as Antti Haapala and Weather Vane suggested. Below is my version:
#include <stdio.h>
#include <stdlib.h>
typedef struct suppliers {
int idSUP;
int coonection;
int bill;
suppliers* next;
}suppliers;
void printlist(suppliers* h);
void insert(suppliers* head, int idSUP, int coonection, int bill);
void main() {
int idSUP;
int coonection;
int bill;
suppliers* head = NULL;
printf("please enter supplier data\n");
while (scanf("%d,%d,%d", &idSUP, &coonection, &bill) != EOF)
insert(head, idSUP, coonection, bill);
printlist(head);
}
void insert(suppliers* head, int idSUP, int coonection, int bill) {
suppliers* t, temp;
t = (struct suppliers*)malloc(sizeof(struct suppliers));
if (t == NULL) {
printf("ERROR");
}
t->idSUP = idSUP;
t->bill = bill;
t->coonection = coonection;
t->next = head;
head = t;
}
void printlist(suppliers* h) { while (h != NULL) { printf("%d", h->bill); h = h->next; } }
I entered the following but the program hung on the scanf after I entered Ctrl+Z.
please enter supplier data
1,1,1
^Z
I don't use scanf much, so I don't know what the problem is. Perhaps this is the same problem the OP had. I don't know. Does anyone know why the code from the OP of the previous question I linked to above doesn't produce any output?
Below is my suggested revisions.
I took a different approach on how the input was entered and how the head structure was implemented. Instead of using a pointer to supplies I created a q structure that held pointers to the first node and the last node. The last node pointer was used to quickly update its next pointer with the node that was just created with the malloc.
Having the last pointer, it wasn't that hard to implement a stack. (Okay, it was hard for me because I'm not all that swift. ;)
I also renamed the fields to have longer names, as is my wont.
Below is my revised code:
#include <stdio.h>
#include <stdlib.h>
typedef struct suppliers {
int idSupplier;
int connection;
int bill;
suppliers* nextPtr;
suppliers* previousPtr;
}suppliers;
typedef struct {
size_t qCount;
suppliers* firstPtr;
suppliers* lastPtr;
}q;
void insert(q* list, int idSupplier, int connection, int bill);
void printList(q list);
void printStack1(q stack);
void printStack2(q stack);
int main() {
int idSupplier;
int connection;
int bill;
int scanCount;
q list;
q stack;
list.firstPtr = NULL;
list.lastPtr = NULL;
list.qCount = 0;
stack.firstPtr = NULL;
stack.lastPtr = NULL;
stack.qCount = 0;
printf("Please enter supplier data. Enter 'q' to quit.\n");
scanCount = scanf("%d, %d, %d", &idSupplier, &connection, &bill);
while (scanCount) {
insert(&list, idSupplier, connection, bill);
insert(&stack, idSupplier, connection, bill);
scanCount = scanf("%d, %d, %d", &idSupplier, &connection, &bill);
}
if (list.qCount > 0) {
printList(list);
}
if (stack.qCount > 0) {
printStack1(stack);
printStack2(stack);
}
}
void insert(q* queue, int idSupplier, int connection, int bill)
{
suppliers* t;
queue->qCount++;
t = (suppliers*)malloc(sizeof(suppliers));
if (t == NULL) {
printf("ERROR");
}
if (queue->firstPtr == NULL) {
queue->firstPtr = t;
}
else {
queue->lastPtr->nextPtr = t;
}
t->previousPtr = queue->lastPtr;
queue->lastPtr = t;
t->idSupplier = idSupplier;
t->bill = bill;
t->connection = connection;
t->nextPtr = NULL;
}
void printList(q list)
{
suppliers* currentPtr;
printf("\n\n");
currentPtr = list.firstPtr;
while (currentPtr != NULL) {
printf("sup=%-3d conn=%-3d bill=%-3d\n", currentPtr->idSupplier,
currentPtr->connection, currentPtr->bill);
currentPtr = currentPtr->nextPtr;
}
}
void printStack1(q stack)
{
suppliers* currentPtr;
if (stack.lastPtr != NULL) {
printf("\n\n");
currentPtr = stack.lastPtr;
do {
printf("sup=%-3d conn=%-3d bill=%-3d\n", currentPtr->idSupplier,
currentPtr->connection, currentPtr->bill);
currentPtr = currentPtr->previousPtr;
}
while (currentPtr != stack.firstPtr);
printf("sup=%-3d conn=%-3d bill=%-3d\n", currentPtr->idSupplier,
currentPtr->connection, currentPtr->bill);
}
}
void printStack2(q stack)
{
suppliers* currentPtr;
printf("\n\n");
currentPtr = stack.lastPtr;
for (size_t i = stack.qCount; i > 0; i--) {
printf("sup=%-3d conn=%-3d bill=%-3d\n", currentPtr->idSupplier,
currentPtr->connection, currentPtr->bill);
currentPtr = currentPtr->previousPtr;
}
}
Here is my output:
Please enter supplier data. Enter 'q' to quit.
1, 2, 3
4, 5, 6
10, 11, 12
20, 21, 22
q
sup=1 conn=2 bill=3
sup=4 conn=5 bill=6
sup=10 conn=11 bill=12
sup=20 conn=21 bill=22
sup=20 conn=21 bill=22
sup=10 conn=11 bill=12
sup=4 conn=5 bill=6
sup=1 conn=2 bill=3
sup=20 conn=21 bill=22
sup=10 conn=11 bill=12
sup=4 conn=5 bill=6
sup=1 conn=2 bill=3
Storing the count of the number of nodes created allowed me to have two different ways of printing the stack. Personally I prefer printStack2, but that's just me.
Hope this helps.
Update: I'm going to mark this as the correct answer, even though it's not. This is one way to implement this stuff, but not likely to be the best way to do it.

Why does it lead to a segmentation fault? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
It just shows me: [1] 10531 Segmentation fault.
I don't what is the problem of my code!(I have defined a list and add an element into the list. But it just failed and I don't know how to change it.)
#include <stdio.h>
#include <stdlib.h>
typedef struct ll {
int val;
struct ll *next;
} ll_t;
void copylist(ll_t* list, int* array, int length) {
int i;
for (i = 0; i < length; i++) {
array[i] = list->val;
list = list->next;
}
}
int main() {
ll_t *list = NULL;
int *array = NULL;
list = malloc(sizeof (ll_t));
list->val = 1;
list->next = NULL;
ll_t *add1 = NULL;
add1 = malloc(sizeof (ll_t));
add1->val = 2;
add1->next = NULL;
list->next = add1;
int j;
copylist(list, array, 2);
for (j = 0; j < 2; j++) {
printf("the content of array is: %d\n", array[j]);
}
return 1;
}
Currently all that you're passing as an array is a null pointer because you instantiate it as
int *array = NULL;
instead of
int *array = malloc(2 * sizeof(int));
which allocates enough space for two integers on the heap. (two being the amount of items you're using in this test).
Also, You should use
int i = 0;
while(list != NULL) {
array[i] = list->val;
list = list->next;
i++;
}
instead of passing the length value, as you know when you reach the end of a linked list when you reach a null value. If someone were to input the wrong length by accident in your program it would lead to another segmentation fault.

Linked list — deletion of nodes which contain prime numbers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have written a code in the C language which will create a linked list. The linked list structre has two fields, namely data and next; data contains integer data, next is a structure pointer.
The program asks the user to input data into the list. Once the data has been entered, the program will go through the list and check which data in the node contains a prime number. If it finds one such node, it will delete it and link the next node to the previous node, but I am getting a segmentation fault error and I am unable to solve.
I am putting below the code. Can you please be kind enough to help me solve it as I do not know how to find the problem?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
typedef struct node *nptr;
nptr H, h, n;
void deletetheprime(struct node**);
void display();
int prime(int);
int main() {
nptr temp1, temp;
int i, N, p;
printf("\n if list is completed enter 999\n");
for (;;) {
printf("\n enter the data \n");
scanf("%d", &i);
if (i == 999)
break;
else
if (H == NULL) {
H = h = (nptr)malloc(sizeof(struct node));
H->data = i;
H->next = NULL;
} else {
n = (nptr)malloc(sizeof(struct node));
n->data = i;
n->next = NULL;
h->next = n;
h = n;
}
}
printf("\n data before deletion\n");
display();
temp = H;
while (temp != NULL) {
N = temp->next->data;
p = prime(N);
if (p == 1) {
deletetheprime(&temp);
} else {
temp = temp->next;
}
}
printf("\n the data after deletion is\n");
display();
return 0;
}
void deletetheprime(struct node **temp2) {
nptr temp, temp1;
temp = *temp2;
temp1 = temp->next;
temp->next = temp->next->next;
free(temp1);
temp = temp->next;
}
int prime(int i) {
int j, p = 0;
for (j = 2; j <= i / 2; i++) {
if (i % j == 0) {
break;
}
}
if (j > i / 2) {
p = 1;
}
return p;
}
void display() {
nptr temp;
temp = H;
while (temp != NULL) {
printf("\n %d", temp->data);
temp = temp->next;
}
}
The problem is here:
while (temp != NULL) {
N = temp->next->data;
When you reach the last element of the list, temp is not NULL, but temp->next is so temp->next->data has undefined behavior.
There are other problems:
your prime() function is inefficient and will return 1 for 0 and 1.
you deletetheprime() function deletes the node and updates the pointer in the callers scope, but the caller does not update the link in the previous node nor the H pointer if the deleted node is the first.
you use global variables for no good reason, you should pass H to display() and make all variables local in main().
you never free the allocated objects, it is good style to free everything you allocate.
you should not hide pointers behind typedefs, make node a typedef for struct node but keep pointers visible, it is a good habit to avoid confusing both the reader and the programmer.
To delete the node, you should use the pointer to link trick:
for (struct node **p = &H; *p;) {
if (prime((*p)->data) {
nptr np = *p;
*p = np->next;
free(np);
} else {
p = &(*p)->next;
}
}
p initially points to the head pointer H and subsequently points to the next member of the previous node. It can be used to update the head pointer or the link in the previous node when a node to be deleted is found.
Here is a corrected and simplified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
int isprime(int n) {
if (n < 2)
return 0;
if (n % 2 == 0)
return n == 2;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
void display(const node *temp) {
while (temp != NULL) {
printf(" %d", temp->data);
temp = temp->next;
}
printf("\n");
}
int main(void) {
node *H = NULL;
node **lastp = &H;
node *n;
int i;
printf("Enter values, when list is completed enter 999\n");
for (;;) {
printf("\n enter the data: ");
if (scanf("%d", &i) != 1 || i == 999)
break;
n = malloc(sizeof(*n));
if (n == NULL)
break;
n->data = i;
n->next = NULL;
*lastp = n;
lastp = &n->next;
}
printf("\n data before deletion: ");
display(H);
for (node **p = &H; *p;) {
if (isprime((*p)->data)) {
n = *p;
*p = n->next;
free(n);
} else {
p = &(*p)->next;
}
}
printf("\n the data after deletion is: ");
display(H);
/* free the list */
while (H != NULL) {
n = H;
H = n->next;
free(n);
}
return 0;
}
I shall attribute your please solve it! stance to your poor command of the English language. Please learn to improve both your communications and your programming skills by carefully studying answers on this site.
The problem occurs here, in main
while(temp!=NULL)
{
N=temp->next->data;
...
You are checking if temp is not NULL, which is correct, but accessing data of next node, which can be NULL, and has to be NULL near the end of the list, which leads to undefined behavior.
Simply modify it to
while(temp!=NULL)
{
N=temp->data;
...
Where you are sure that temp isn't NULL and you won't get segmentation error here. And it'll work.
Or if you need to access data of temp->next->next node, you've got to check if next->next isn't NULL as well.
while(temp!=NULL)
{
if (temp->next->next != NULL)
{
N=temp->next->data;
}
else // temp->next->next is NULL so you can't access the data
...

Circular Linked list is crashing while trying to print [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
So I'm working on a program, that will eventually simulate a lame version of duck duck goose (actually called duck duck boot by the professor). When I read the problem circular linked list is what popped out towards me. Though I am very new at using linked lists in general.
It seems like the program is creating and assigning the nodes, but I crash when I try to print them.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[20];
struct jimmysFriend *next;
} jimmysFriend;
jimmysFriend *createNode();
void populateList(jimmysFriend *bestFriend, int numberOfFriends);
//void duckDuckBoot();
void printList(jimmysFriend *bestFriend);
int main(void) {
int i;
int cases;
int numberOfFriends;
scanf("%d", &cases);
for (i = 0; i < cases; i++) {
scanf("%d", &numberOfFriends);
jimmysFriend *bestFriend; //head
bestFriend = NULL;
populateList(bestFriend, numberOfFriends);
printList(bestFriend);
}
return 0;
}
void populateList(jimmysFriend *bestFriend, int numberOfFriends) {
int i; //Where I actually create the circular list.
jimmysFriend *aFriend;
for (i = 0; i < numberOfFriends; i++) {
aFriend = createNode();
if (bestFriend == NULL) {
bestFriend = aFriend;
aFriend->next = aFriend;
} else
if (bestFriend != NULL) {
jimmysFriend *temptr;
aFriend->next = bestFriend;
temptr = bestFriend;
while (temptr->next != bestFriend) {
temptr = temptr->next;
}
temptr->next = aFriend;
}
}
}
jimmysFriend *createNode() { //Creates a node
jimmysFriend *aFriend;
aFriend = malloc(sizeof(jimmysFriend));
if (aFriend != NULL) {
scanf("%s", aFriend->name);
}
return aFriend;
}
void printList(jimmysFriend *bestFriend) { //Problem area?
jimmysFriend *temptr;
temptr = bestFriend;
while (temptr->next != bestFriend) {
printf("%s\n", temptr->name);
temptr = temptr->next;
}
}
There are 2 problems.
The first is that you're not passing bestFriend to populateList() by address, so it doesn't get changed. populateList() should look like this:
void populateList(jimmysFriend **bestFriend, int numberOfFriends){
int i; //Where I actually create the circular list.
jimmysFriend* aFriend;
for(i = 0; i < numberOfFriends; i++){
aFriend = createNode();
if(*bestFriend == NULL){
*bestFriend = aFriend;
aFriend->next = aFriend;
}
else if(*bestFriend != NULL){
jimmysFriend* temptr;
aFriend->next = *bestFriend;
temptr = *bestFriend;
while(temptr->next != *bestFriend){
temptr = temptr-> next;
}
temptr->next = aFriend;
}
}
}
And then you call it like this:
populateList(&bestFriend, numberOfFriends);
The second problem is that your condition for the printList() loop is wrong. There is more than one way of writing it, but this do loop works:
void printList(jimmysFriend* bestFriend){ //Problem area?
if (bestFriend != NULL) {
jimmysFriend* temptr = bestFriend;
do {
printf("%s\n", temptr->name);
temptr = temptr->next;
} while (temptr != bestFriend);
}
}
Reference: Circular Linked List
In populateList() Jimmy's best friend isn't really pointed at the head of the list when you are done with the function. The assignment that you make in populateList() is lost.
Pass jimmy's best friend as the address of the pointer to the function. So populateList() will accept jimmysFriend **bestFriend. Then when you try to store the head there you will assign the node you want to be the head to *bestFriend.
You can always validate that by checking if Jimmy's best friend is NULL right before you call printList().
populateList ( &bestFriend, numberOfFriends);

Segmentation Fault issue, unable to detect [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Can someone help me with this piece of code. I am getting segmentation fault. Kindly help me out as to where I am going wrong.
#include <stdio.h>
#include <stdlib.h>
struct city
{
int x;
int pop;
struct city *next;
};
struct list
{
struct city *head;
};
void insert(struct list *list1,int a,int b)
{
struct city *node = (struct city *)malloc(sizeof(struct city));
node->x=a;
node->pop = b;
if(list1->head!=NULL)
{
node->next=list1->head;
}
list1->head=node;
}
void initialize_list(struct list *list1)
{
list1->head = NULL;
}
void display(struct list *list)
{
struct city *temp = list->head;
while(temp!=NULL)
{
printf("%d %d\n",temp->x,temp->pop);
temp=temp->next;
}
free(temp);
}
void getdata(int *x)
{
char s[1000];
char c;
scanf("%[^\n]%*s",s);
char *p=s;
int i =0;
while(*p!='\0')
{
while(*p==' ' && *p!='\0')
p++;
if(*p!='\0')
x[i] = atoi(p);
while(*p!=' ' && *p!='\0')
p++;
i++;
}
}
int max(int a,int b)
{
if(a>b)
return a;
else
return b;
}
int total(struct list *link)
{
struct city *r1,*r2;
r1=link->head;
r2 = r1;
int S=0;
while(r1!=NULL)
{
r2 = r1;
while(r2!=NULL)
{
S=S+max(r1->pop,r2->pop)*abs((r2->x)-(r1->x));
r2=r2->next;
}
r1=r1->next;
}
printf("\n%d",S);
free(r1);
free(r2);
return S;
}
int main()
{
int T;
int *x,*pop;
int _no_city;
char c;
scanf("%d",&T);
struct list **link = (struct list **)malloc(T*sizeof(struct list*));
for(int i=0;i<T;i++)
{
link[i]=(struct list *)malloc(sizeof(struct list));
}
for(int i =0;i<T;i++)
{
scanf("%d",&_no_city);
x = (int *)malloc(_no_city*sizeof(int));
pop = (int *)malloc(_no_city*sizeof(int));
while((c= getchar()) != '\n' && c != EOF)
fflush(stdin);
getdata(x);
getdata(pop);
initialize_list(link[i]);
for(int j=0;i<_no_city;j++)
{
insert(link[i],x[j],pop[j]);
}
free(x);
free(pop);
}
for(int i=0;i<T;i++)
{
printf("%d",total(link[i]));
}
}
Is the problem lying with my declaring a pointer to pointer, I did that so that I can create an array of pointers of variable length.
There are quite a few bugs in your program, but this one
for(int j=0;i<_no_city;j++)
{
insert(link[i],x[j],pop[j]);
}
will run off the end of x and pop because your loop condition is wrong, and is probably the cause of your crash.

Resources