Segmentation Error with a linked list while loop - c

I am having trouble with a project I am working on for class. I am particularly having trouble with recursively printing a linked list of spheres. Whenever the program runs over the particular part:
ss=ss->next;
there is a Segmentation fault: 11. What could the problem be?
(Note: I've included the necessary structssphereandsphere_list, and left outrgbandvec` so as to not clutter up the code.)
typedef struct sphere {
vec *center;
double radius;
rgb *color;
} sphere;
typedef struct sphere_list sphere_list;
/* convention: NULL is the empty sphere list */
struct sphere_list {
sphere *s;
sphere_list *next;
};
void sl_print(sphere_list *ss)
{
if(ss==NULL)
printf("SPHERE LIST EMPTY\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("SPHERE LIST:\n");
int i=1;
while(ss->s!=NULL){
printf("\t%d ", i);
sphere_print(ss->s);
if(ss->next==NULL){
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
return;
}
ss=ss->next;
i++;
}
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
return;
}

try this:
void sl_print(sphere_list *ss)
{
if(ss==NULL){
printf("SPHERE LIST EMPTY\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("SPHERE LIST:\n");
return ;
}
int i=1;
while(ss != NULL){
printf("\t%d ", i);
sphere_print(ss->s);
ss=ss->next;
i++;
}
}

struct sphere_list {
sphere *s;
sphere_list *next;
};
have you allocated space for sphere *s and made the pointer point to valid memory?, I would have done this, just a suggestion.
typedef struct sphere {
vec *center;
double radius;
rgb *color;
//included the pointer in the struct//
struct sphere *next
} sphere;
Also, typedef structs are not favoured by most people.makes the code harder to read.

You made an error in your loop conditions. You have to test next value, because this is why you move on on sphere_list.
void sl_print(sphere_list *ss)
{
sphere_list *tmp = ss;
if(ss==NULL)
printf("SPHERE LIST EMPTY\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("SPHERE LIST:\n");
int i=1;
while(tmp!=NULL){
printf("\t%d ", i);
if (tmp->s != NULL)
sphere_print(tmp->s);
if(tmp->next==NULL){
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
return;
}
tmp=tmp->next;
i++;
}
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
return;
}
Modified*

Related

Tokenizing elements and storing them in an n-ary tree

My goal is to tokenize the strings using delimiter '.' and then store them in the form of n-ary tree, with successive children containing the tokenized elements. I have problem storing the elements in an array of strings. And hence not able to store them. I also want to ask functioning of strtok() in C.
Here is my code
int main()
{ int opt,n;
printf("Option,then number of cases:\n");
scanf("%d %d",&opt,&n);
node *root=createNode("root");
char **words=arr_strings(size,n);
char *dns_word=malloc(sizeof(char)*size);
char *app=malloc(sizeof(char)*size);
app[0]='.';
char *dup=malloc(sizeof(char)*size);
char *store=malloc(sizeof(char)*size);
for(int i=0;i<n;i++)
{printf("Word %d: ",i+1);
scanf("%s",words[i]);
*dup=*app;
strcat(dup,words[i]);
strcpy(words[i],dup);
strcat(words[i],app);
*store=*words[i];
printf("Word %d:%s\n",i,words[i]);
int j=0;
dns_word=strtok(words[i],".");
node *temp=createNode(dns_word);
while(dns_word!=NULL){
if(i==0)
{//printf("Entered one child condition\n");
if(j==0)
{root->child=temp;
}
else
{
temp->child=createNode(dns_word);
temp->children++;
temp=temp->child;
}
}
else
{
//printf("Entering else of inserting loop\n");
//printf("dns_word:%s\n",dns_word);
int t=root->children;
node* copy=root->child;
for(int j=1;j<root->children;j++)
{copy=copy->next;
}
if(j==0)
{copy->next=temp;copy->children++;}
else
{
temp->child=createNode(dns_word);
temp->children++;
temp=temp->child;
}
}
dns_word=strtok(NULL,".");
j++;
}
//printf("Word %d:%s\n",i,words[i]);
root->children++;
}
//Ignore this
printf("Root,child:%s\n",root->child->word);
printf("Root,child,next:%s\n",((root->child)->next)->word);
//print(root->child);
return 0;
}
The structure of the node is provided here.
struct node{
char *word;
int children;
struct node* child;
struct node* next;
};
typedef struct node node;
The createNode function is as follows:
node* createNode(char *word)
{
node* new=malloc(sizeof(node));
new->word=word;
new->child=NULL;
new->next=NULL;
new->children=0;
return new;
}

Finding path between nodes using BFS in C language

I'm new to C language and it's been harder for me to work with pointers after working in Java😥
I was trying to write a code of finding a path (not necessary minimum) between two nodes in a graph using breadth-first-search.
Here is my code :
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 200
void push(int a);
int pop(void);
void bfs(int a,int b,int len);
int nextnode(int a);
typedef struct node{
int data;
struct node* next;
}node;
int res[MAXSIZE];
int visited[MAXSIZE];
int rear,front;
node* graph[MAXSIZE];
int len;
int path[MAXSIZE];
int nextnode(int a)
{
if(graph[a]==NULL)
return -1;
else
{
struct node* c=graph[a];
while(visited[c->data]!=1 && c!=NULL)
{
c=c->next;
}
if(c==NULL)
return -1;
else
return c->data;
}
}
void push(int a)
{
path[rear]=a;
rear++;
}
int pop()
{
if(front==rear)
return -1;
int num=path[front];
front++;
return num;
}
int main()
{
rear=0;
len=0;
front=0;
int n,e;
int i,a,b;
printf("%s\n%s", "Inputting Graph... ","Enter number of nodes and edges: ");
scanf("%d %d",&n,&e);
printf("%s %d %s\n", "Graph Created with",n,"nodes without any edge.");
printf("%s\n","Enter the edges in 1 2 format if an edge exist from Node 1 to Node 2" );
for(i=1;i<=n;i++)
{
graph[i]=NULL;
visited[i]=0;
}
struct node* new = (struct node*)malloc(sizeof(struct node));
for(i=0;i<e;i++)
{
scanf("%d %d",&a,&b);
new->data=b;
new->next=NULL;
struct node* curr=graph[a];
if(curr==NULL)
{
graph[a]=new;
}
else
{
while(curr->next!=NULL)
{
curr=curr->next;
}
curr->next=new;
}
}
printf("%s\n", "Graph Created Successfully.");
printf("%s", "Enter the node numbers between which the path is to be found between: ");
scanf("%d %d",&a,&b);
bfs(a,b,0);
printf("Length is %d\n",len);
for(i=1;i<=len;i++)
{
printf("%d\n",res[len]);
}
}
void bfs(int a,int b,int len)
{
int c;
visited[a]=1;
int flag=0;
while(a!=-1)
{
c=nextnode(a);
while(c!=-1)
{
c=nextnode(a);
if(c==b)
{
flag=1;
break;
}
push(c);
visited[c]=1;
}
len++;
res[len]=a;
if(flag==1)
{
res[len]=b;
break;
}
a=pop();
}
}
I know it's huge, but please mind going through it once. The problem I'm getting is Segmentation Fault after I input all the values, and before dfs() function call! Please Help.
For understanding: I have used array of Lists. Each array index denotes a node and the list denotes all the edges it is connected to. eg: if my Graph has 1->2, 1->3, 2-3 edges;
graph[1] will have a list 2->3->NULL. And graph[2] will have 3->NULL.
Thank you.
EDIT
As pointed out by Aditi, the error was in the line where nextnode function ran the while loop. After changing the code to
while(c != NULL && visited[c->data] == 1 )
the program ran flawlessly.
Thanks!
I think what you are trying to do is not graph[i] = NULL but graph[i]->next = NULL

Storing input from user into linked list using array

So I'm trying to get input from user and store it in linked list, using array (every 5 chars a new linked list is created). After getting EOF I want to print the input (actually print the arrays in each linked list)
here is my code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
typedef struct charNode {
int arr[MAX];
struct charNode *next;
} charNode;
void addNode();
void printAll();
int main(){
int c,i;
charNode *head=malloc(sizeof(charNode));
charNode *current=head;
while((c=getchar())!=EOF){
while(i<MAX){
current->arr[i++]=c;
}
i=0;
addNode(current);
}
printAll(head);
return 0;
}
void addNode(charNode *current){
struct charNode *link = (struct charNode*) malloc(sizeof(struct charNode));
current->next =link;
link->next = NULL;
current=current->next;
}
void printAll(charNode *head){
int j=0;
while(head->next!=NULL){
while(j<MAX){
printf("\n %d \t",head->arr[j++]);
}
printAll(head->next);
}
return;
}
and I'm getting "Segmentation fault (core dumped)" error..
This is Undefined behavior:
int c,i;
charNode *head=malloc(sizeof(charNode));
charNode *current=head;
while((c=getchar())!=EOF){
while(i<MAX){
current->arr[i++]=c;
}
since you are using i uninitialized to access your array, which could produce the Segmentation fault.
Change this:
printf("\n %d \t",head->arr[j++]);
to this:
printf("\n %c \t",head->arr[j++]);
so that you print characters, instead of numbers.
Simply initialize i to 0 for a start, happy debugging! =)
int main(){
char c;
charNode *head=malloc(sizeof(charNode));
charNode *current=head;
int i = 0;
while((c=getchar())!=EOF){
getchar();
while(i<MAX){
current->arr[i++]=c;
}
i=0;
addNode(&current);
}
printAll(head);
return 0;
}
void addNode(charNode **current){
struct charNode *link = malloc(sizeof(struct charNode));
link->next = NULL;
(*current)->next =link;
*current=(*current)->next;
}
void printAll(charNode *head){
int j=0;
if(head!=NULL){
while(j<MAX){
printf("%c\n",head->arr[j++]);
}
if(head->next != NULL)
printAll(head->next);
}
}
I changed your code a bit. Especially take a good look at addNode(). Now it works correctly

Graph representation with dynamic linked lists

I start by saying I am quite new to C and right now, I struggle with some very non intuitive mistakes. I've tried for quite a while now to reach at some solution, but I am always reaching a dead end.
I am trying to build a couple of functions for inserting and displaying a graph via dynamic linked lists. At compile time everything works just fine, but the elements seem not to be well displayed. Actually, just like in the image below, only the first element of the node is displayed.
So the question is what is causing these errors and warnings and what should I do to remove them?
If you take a look at the code below, you will see that it has a few warnings(I don't know why they appear - I am using Code Blocks in Ubuntu with the GNU compiler) and also problems at displaying the elements of the graph. The problem lies most likely in the display_graph function, but I can't realize where.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct AdjListNode {
int dest;
struct LIST_NODE *next;
} LIST_NODE;
typedef struct AdjList {
struct LIST_NODE *head;
} ADJACENCY_LIST;
LIST_NODE *create_node(int dest) {
LIST_NODE *nod;
if(dest<0) exit(0);
nod = (LIST_NODE*)malloc(sizeof(LIST_NODE));
if(nod==NULL) {
printf("Problems at memory allocation!");
exit(0);
}
nod->dest = dest;
nod->next = NULL;
return (LIST_NODE*)nod;
}
void display_graph(ADJACENCY_LIST *v) {
int s, i;
LIST_NODE *nod;
s = sizeof(v);
for(i=0;i<=s;i++) {
nod = v[i].head;
//citeste lista cu head in primul nod
while(nod!=NULL) {
printf("Data from node: %d \n", nod->dest);
nod = nod->next;
}
}
}
int main()
{
int n; //number of graph nodes
int i; //just a counter
int dest; dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative
char c;
ADJACENCY_LIST *t;
printf("The number of nodes of the graph: ");
scanf("%d", &n);
t = (ADJACENCY_LIST*)malloc(n*sizeof(ADJACENCY_LIST));
/* We make a loop for the nodes and each node has a while thru which I make the links */
for(i=0;i<n;i++) {
c = 'D'; // Initializing
printf("Specify the links of the node %d with the others:\n", i);
int contor; contor = 0;
while(c=='D') {
LIST_NODE *nod;
printf("The link with node: ");
scanf("%d%*c", &dest);
if(dest>=0){
nod = create_node(dest);
if(contor==0) t[i].head = (LIST_NODE*)nod; // just make the first node a head node
} else nod = NULL;
//verificam daca vrem sa continuam
printf("Do you want to link any other node to %d?(D to add, anything else STOP\n)", i);
c = getchar();
contor++; //increment counter
}
// inchidem lista
}
display_graph(t);
return 0;
}
Any help will be greatly appreciated!
EDIT:
As Christhofe(confirmed the problem) and Abhishek Vasisht pointed out the size of the vector v returned actually the size of the pointer.
But, there are still some warnings which I don't know why they still appear...all are
||=== Build: Debug in Grafuri1 (compiler: GNU GCC Compiler) ===|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c||In function ‘display_graph’:|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|33|warning: assignment from incompatible pointer type|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|38|warning: assignment from incompatible pointer type|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|28|warning: unused variable ‘s’ [-Wunused-variable]|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c||In function ‘main’:|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|71|warning: assignment from incompatible pointer type|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|76|warning: assignment from incompatible pointer type|
||=== Build finished: 0 error(s), 5 warning(s) (0 minute(s), 0 second(s)) ===|
The main thing is the program is functional now. Thanks a lot guys! Really helpful!!
Try this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct AdjListNode {
int dest;
struct LIST_NODE *next;
} LIST_NODE;
typedef struct AdjList {
struct LIST_NODE *head;
} ADJACENCY_LIST;
LIST_NODE *create_node(int dest) {
LIST_NODE *nod;
if (dest < 0) exit(0);
nod = (LIST_NODE*)malloc(sizeof(LIST_NODE));
if (nod == NULL) {
printf("Problems at memory allocation!");
exit(0);
}
nod->dest = dest;
nod->next = NULL;
return (LIST_NODE*)nod;
}
void display_graph(ADJACENCY_LIST *v,int values) {
int s, i;
LIST_NODE *nod;
for (i = 0; i < values; ++i)
{
nod = v[i].head;
printf("Data from node: %d \n", i);
while (nod != NULL)
{
printf("Data : %d \n", nod->dest);
nod = nod->next;
}
}
}
int main()
{
int n; //number of graph nodes
int i; //just a counter
int dest; dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative
char* c = (char*)(malloc(sizeof(char)));
ADJACENCY_LIST *t;
LIST_NODE *last_added;
printf("The number of nodes of the graph: ");
scanf("%d", &n);
t = (ADJACENCY_LIST*)calloc(n,sizeof(ADJACENCY_LIST));
/* We make a loop for the nodes and each node has a while thru which I make the links */
for (i = 0; i < n; i++) {
//c = 'D'; // Initializing
printf("Specify the links of the node %d with the others:\n", i);
int contor; contor = 0;
do {
LIST_NODE *nod;
printf("The link with node: ");
scanf("%d", &dest);
if (dest >= 0) {
nod = create_node(dest);
if (contor == 0)
{
t[i].head = (LIST_NODE*)nod; // just make the first node a head node
last_added = nod;
}
else
{
last_added->next = nod;
last_added = nod;
}
}
//verificam daca vrem sa continuam
printf("Do you want to link any other node to %d?(D to add, anything else STOP\n)", i);
fflush(stdin);
*c = getchar();
contor++; //increment counter
} while (*c == 'D');
}
display_graph(t,n);
return 0;
}
the following code compiles cleanly, works.
It does not have the capability of having a list of nodes for each entry in the first level list of pointers.
You can easily add that feature.
You also need to add the feature of passing each malloc'd node to free()
especially when an error has occurred
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct AdjListNode
{
int dest;
struct AdjListNode *next;
} ;
// declare list of pointers to nodes
static struct AdjListNode **head = NULL;
struct AdjListNode *create_node(int dest)
{
struct AdjListNode *nod;
nod = malloc(sizeof(struct AdjListNode));
if(nod==NULL)
{
perror(" malloc failed" );
printf("Problems at memory allocation!");
exit(-1);
}
// implied else, malloc successful
nod->dest = dest;
nod->next = NULL;
return nod;
} // end function: create_node
int main( void )
{
int n; //number of graph nodes
int i; //just a counter
int dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative
printf("The number of nodes of the graph: ");
if( 1 != scanf("%d", &n) )
{ // then scanf failed
perror( "scanf for number of nodes failed" );
exit( -1 );
}
// implied else, scanf successful
// set ptr to list of node pointers
head = malloc(n*sizeof(struct AdjList*));
if( NULL == head )
{ // then malloc failed
perror( "malloc failed for list of pointers to nodes" );
exit( -1 );
}
// implied else, malloc successful
// initialize list of pointers (makes for easier cleanup, especially when a failure occurs
memset( head, 0x00, n*sizeof(struct AdjList*) );
/* We make a loop for the nodes and each node has a while thru which I make the links */
for(i=0;i<n;i++)
{
printf("Enter Dest value for %d of %d:", i, n);
if( 1 != scanf("%d", &dest) ) // note %d will skip over leading white space like newlines
{ // then scanf failed
perror( "scanf for dest value failed" );
exit(-1);
}
// implied else, scanf successful
if(dest>=0)
{
head[i] = create_node(dest);
}
else
{
printf( "Dest value must be >= 0\n" );
}
//verificam daca vrem sa continuam
// inchidem lista
} // end for
return 0;
} // end function: main

Sorting of double linked list in C

I created a program to sort double linked list in ascending order, and the result was unexpected, but when I used the same program for descending order by changing a line in it, it worked perfectly. Please tell where m going wrong
/*Structure of double linked list */
struct dlink
{
int num;
struct dlink *plink; //previous address
struct dlink *nlink; //next address
};
void main()
{
clrscr();
struct dlink *st;
st=NULL;
append(&st,100); //to put values in double linked list
append(&st,32);
append(&st,200);
append(&st,107);
display(st);
ascending(&st);
display(st);
getch();
}
/* function to add values to double linked list */
void append(struct dlink **q,int n)
{
struct dlink *temp,*r;
temp=*q;
if(temp==NULL)
{
temp=(dlink *)malloc(sizeof(dlink));
temp->num=n;
temp->plink=NULL;
temp->nlink=NULL;
*q=temp;
}
else
{
while(temp->nlink!=NULL)
temp=temp->nlink;
r=(dlink *)malloc(sizeof(dlink));
r->num=n;
r->nlink=NULL;
r->plink=temp;
temp->nlink=r;
}
}
void ascending(struct dlink **q)
{
struct dlink *temp,*s,*p=NULL;
temp=*q;
int a=count(*q);
printf(" a %d ",a);
for(int i=0;i<a;i++,temp=temp->nlink)
{
s=temp->nlink;
for(int j=i+1;j<=a;j++,s=s->nlink)
{
if((temp->num) < (s->num)) //for ascending i was using //if(temp->num > s->num but it is not getting desired result it is just printing //one value and by this one for descending order program is working perfectly //for descending order
{
(s->plink)->nlink=s->nlink;
if(s->nlink!=NULL)
(s->nlink)->plink=s->plink;
s->plink=temp->plink;
s->nlink=temp;
temp=s;
(temp->nlink)->plink=temp;
}
}
if(i==0)
*q=temp;
if(i!=0)
{
p->nlink=temp;
temp->plink=p;
}
p=temp;
}
temp=*q;
/* To see if the addresse , previous address , next address are correct */
while(temp!=NULL)
{
printf("as %u %u %u\n",temp->plink,temp->nlink,temp);
temp=temp->nlink;
}
}
Look at this part
int a=count(*q);
for(int i=0; i<a; i++,temp=temp->nlink)
{
s=temp->nlink;
for(int j=i+1; j<=a; j++,s=s->nlink)
{ ....
Seems you are using indexes from 0 (first loop) to count(*q) (second) for a list with count(*g) elements.
Something is probably wrong in your algorithm - even if it doesnt cause "index out of bounds" errors (because you don't use arrays).
And it appears when you try to sort the second way, because you have not tested the first way seriously enough.

Resources