I am trying to implement Hierholzer's algorithm using C.
I have made a push function for a simple stack implemented using doubly linked list but the pointer always moves on to the else condition, even when the starting node is empty.
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<stddef.h>
typedef struct node
{
int source;
int num;
struct node *l, *r;
int done;
}node;
void push(int source, int num, struct node *head)
{
node *n = malloc(sizeof(node));
n->num = num;
n->l = NULL;
n->done = 0;
n->source = source;
if (*head == NULL)
{
head = n;
head -> r = NULL;
}
else
{
n -> r = head;
head->l = n;
head = n;
}
}
int pop(node *head)
{
if(head == NULL)
{
return -1;
}
else
{
node *temp = head;
head = head->r;
int num = temp->num;
free(temp);
return num;
}
}
void append(node *extra, node *head)
{
node *temp = extra;
while(temp->r != NULL)
{
temp = temp->r;
}
temp->r = head;
head->l = temp;
head = extra;
}
node** read(int num)
{
char a[2000] = "Assignment1.txt" ,c[1000];
FILE *f = fopen(a,"r");
printf("Got file\n");
node *adj[num];
int i=0;
node *l;
printf("l: %d\n", l);
while(fscanf(f,"%s",c))
{
char *p = strtok(c, ",");
while(p!=NULL)
{
push(i, atoi(p), l);
p = strtok (NULL, ",");
}
adj[i++] = l;
}
printf("Adjacency list created\n");
return adj;
}
node* euler(node *adj[],int n, int i)
{
node *cpath = NULL;
node *fin = NULL;
node *extra;
node *temp = adj[i];
node *tempi;
while(temp!=NULL)
{
if(temp->r->r == NULL)
{
tempi = temp;
}
if(temp->done == 0)
{
temp->done = 1;
push(i, temp->num, cpath);
extra = euler(adj, n, temp->num);
append(extra, cpath);
}
else
{
temp = temp->r;
}
}
while(tempi->l != NULL)
{
push(i,tempi->num, fin);
extra = euler(adj, n, tempi->num);
append(tempi, fin);
tempi = tempi->l;
}
if(tempi != NULL)
{
push(i,tempi->num, fin);
extra = euler(adj, n, tempi->num);
append(tempi, fin);
}
return fin;
}
int main()
{
int n;
printf("Enter the number of vertices: ");
scanf("%d", &n);
node **adj = read(n);
node *fin = euler(adj, n, 0);
node *temp = fin;
while(temp!=NULL)
{
printf("%d ", temp->num);
temp = temp->r;
}
return 0;
}
I am yet to debug the entire code but I am getting stuck at the read() function where the input is an Assignment1.txt which includes:
2,3
3,1
1,2
I am not able to understand why I am getting a segmentation fault.
The function deals with a copy of the value of the passed to it pointer to the head node. So the original pointer itself is not changed in the function. It is the copy of the value of the passed pointer that is changed within the function.
You need to pass the pointer by reference that is indirectly through pointer to the pointer.
The function can be declared and defined the following way.
int push( struct node **head, int source, int num )
{
node *n = malloc(sizeof(node));
int success = n != NULL;
if ( success )
{
n->source = source;
n->num = num;
n->done = 0;
n->l = NULL;
n->r = *head;
if ( *head != NULL ) ( *head )->l = n;
*head = n;
}
return success;
}
In read function you are returning adj. However, it is a local variable. You are not using malloc type function. So, local variables destroy after function returned. Therefore, you are trying to access a random place when you try to access adj in main. I guess the problem is caused by this reason.
Related
I'm relearning linked list data structure and I stumbled upon this problem.
#include <stdlib.h>
#include <stdio.h>
struct Node{
char url[50];
struct Node *next;
};
typedef struct Node Node;
void add_url(Node * h, Node * c, Node * n){
Node * temp;
temp = malloc(sizeof(Node));
printf("\nType or paste your URL: ");
scanf("%s", temp->url);
if(h == NULL){
h = temp;
h->next = NULL;
c = h;
}else{
c->next = temp;
c = c->next;
n = c->next;
}
}
int main(){
Node * h = NULL; // head
Node * c; // current
Node * n; // next
add_url(h, c, n);
printf("%s", h->url);
return 0;
}
Why is the output NULL? How exactly do you get a string input from a pointer to struct?
Here is a possible solution. I have added some checks to avoid segmentation fault (access violation), buffer overflow in scanf, initialized variables and the function now returns the new head (Could instead return current node).
#include <stdlib.h>
#include <stdio.h>
struct Node {
char url[50];
struct Node* next;
};
typedef struct Node Node;
Node *add_url(Node** h, Node** c, Node** n) {
Node* temp;
if ((h == NULL) || (c == NULL) || (n == NULL))
return NULL;
if ((temp = malloc(sizeof(Node))) == NULL)
return NULL;
printf("\nType or paste your URL: ");
if (scanf("%50s", temp->url) != 1)
return NULL;
if (*h == NULL) {
temp->next = NULL;
*h = temp;
*c = *h;
}
else {
(*c)->next = temp;
*c = temp;
*n = temp;
}
return *h;
}
int main() {
Node* h = NULL; // head
Node* c = NULL; // current
Node* n = NULL; // next
if (add_url(&h, &c, &n) == NULL) {
perror("add_url failed: ");
return 1;
}
printf("%s", h->url);
return 0;
}
I am just implementing circular linked list program but in this program i am having to face trouble, as you can see I am going to past code below, when I call insertAtLast and isertAtFirst function it's work fine but as soon as I call viewList function to view list item but it shows "there is no items" which I wrote inside if block for run when last is null but in this program I have already inserted two items before viewList call so I think last should not be null because I have already inserted item, I want to print all items of list by viewList function
#include <stdio.h>
#include <stdlib.h>`
#include <conio.h>
struct node {
int item;
struct node *next;
};
void insertAtFirst(struct node **last, int data) {
struct node *n, *t;
n = malloc(sizeof(struct node));
n->item = data;
t = *last;
if(*last == NULL) {
n->next = n;
t = n;
}
else {
n->next = t->next;
t->next = n;
}
}
void insertAtLast(struct node **last, int data) {
struct node *n, *t;
n = malloc(sizeof(struct node));
n->item = data;
t = *last;
if(*last == NULL) {
n->next = n;
t = n;
}
else {
n->next = t->next;
t->next = n;
t = n;
}
}
void viewList(struct node *last) {
struct node *start;
if(last == NULL)
printf("\n there is no items......");
else {
start = last->next;
while(start->next != last->next) {
printf("%d ", start->item);
start = start->next;
}
}
}
int main(){
struct node *last = NULL;
insertAtLast(&last, 3);
insertAtFirst(&last, 5);
viewList(last);
return 0;
}
You should use *last = n instead of t = n.
And that's because the latter just causes the variable t to point to n and that's it. But by doing *last = n you will at least insert a value in the list even if last == NULL I guess that would give the desired output.
The program is supposed to take a user entered integer and convert it into binary through a stack of singly linked lists. I think it's either my toBin() function or my printStack() function that's causing the infinite loop.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct node_def node;
struct node_def
{
int val;
node *next;
};
node *head;
void push(int val);
void pop(node *head);
int top();
void printStack();
int toBin(int val);
int main()
{
int num = 0;
printf("Enter an integer: ");
scanf("%d", &num);
push(num);
toBin(num);
printStack();
return 0;
}
void push(int val)
{
node *new;
new = malloc(sizeof(node));
if (head == NULL)
{
head = malloc(sizeof(node));
head->next = NULL;
head->val = val;
}
else
{
new->next = head;
new->val = val;
head = new;
}
return;
}
void pop(node *head)
{
node *tmp;
if(head == NULL)
{
printf("Stack is Empty\n");
return;
}
else
{
tmp = head;
head = head->next;
free(tmp);
}
return;
}
int top()
{
return(head->val);
}
void printStack()
{
node *tmp;
tmp = head;
if(head == NULL)
{
return;
}
while(head != NULL)
{
printf("%d ", head->val);
head = head->next;
}
printf("\n");
return;
}
int toBin(int val)
{
pop(head);
int i = 1, remainder, binary;
while(val != 0)
{
remainder = val % 2;
binary = binary + remainder * i;
val = val / 2;
i = i * 10;
push(binary);
}
return val;
}
You run into an infinite loop due to not properly initialising your variables. In particular, you have no guarantees that your node* head will be initialised to NULL, or that your int variables in toBin() will be initialised to zero.
Always, always, always initialise your variables when programming in C/C++.
Fixing these bugs and removing unused code leaves us with:
#include <stdio.h>
#include <stdlib.h>
typedef struct node_def node;
struct node_def
{
int val;
node *next;
};
/* Note that we are initialising the global variable to NULL. */
node *head = NULL;
void push(int val);
void printStack();
int toBin(int val);
int main()
{
int num = 0;
printf("Enter an integer: ");
scanf("%d", &num);
/* Removed push(num), as you're using parameters in the following call: */
toBin(num);
printStack();
return 0;
}
/* Changed printStack to use a tmp pointer to
traverse the stack without mutating it */
void printStack()
{
node* tmp = head;
while(tmp != NULL)
{
printf("%d ", tmp->val);
tmp = tmp->next;
}
printf("\n");
return;
}
int toBin(int val)
{
/* Removed pop() as you're getting val from parameters */
/* Also initialising remainder and binary variables */
int i = 1, remainder = 0, binary = 0;
while(val != 0)
{
remainder = val % 2;
binary = binary + remainder * i;
val = val / 2;
i = i * 10;
push(binary);
}
return val;
}
/* It's a stack so no if's are necessary for pushing */
void push(int val)
{
node *new = malloc(sizeof(node));
new->val = val;
new->next = head;
head = new;
return;
}
I am new to C and try to learn how to implement C on linked list. I am really confused why I can't access myList in the main function? because when I try to myList->data, it's segmentation fault. I think there's some error in my addtohead function?
Below is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct NODE{
int data;
struct NODE *next;
}node;
node * myList;
node * addToHead(node*, int);
void printList();
int main(){
myList = NULL;
int input;
while (scanf("%i",&input) == 1){
addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
void printList(node* head){
node *temp = head;
while(temp != NULL){
printf("%d ", temp->data);
temp = temp -> next;
}
printf("\n");
}
Your addToHead function is supposed to return the mallocated memory back to caller.
So you should assign the return value to mylist at first:
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1){
myList = addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
Into your addToHead function you wrote
head = temp;
But head has local scope and the assigned value is not reflected to the pointer myList.
To do so you have to use pointer to pointer.
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1)
{
if (addToHead(&myList, input) == true)
{
printf("%d \n", myList->data);
}
else
{
fprintf(stderr, "Error addToHead\n");
}
}
return 0;
}
bool addToHead(node** head, int newData){
node *temp = malloc(sizeof(node));
if (temp != NULL)
{
temp -> data = newData;
temp -> next = NULL;
if(head != NULL)
{
temp -> next = *head;
}
*head = temp;
return true;
}
return false;
}
Finally always remember to check the malloc return value: it can fail.
You return the new head node from addToHead, but you don't do anything with it. You need to assign this value to myList to update it:
myList = addToHead(myList, input);
Also, you misspelled a variable on the following line:
printf("%d \n", myListd->data);
It should be:
printf("%d \n", myList->data);
In this function definition
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
The parameter node* head is a local variable of the function. Any changes of the parameter will not influence on the original argument. The function parameters will be destroyed after exiting the function.
You can consider the function definition and its call the following way
addToHead(myList, input);
//...
node* addToHead(/*node* head, int newData*/){
node *head = myList;
int newData = input;
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
So the original variable myList will not be changed after the function call. You have to assign explicitly the returned value to the variable
myList = addToHead(myList, input);
Also the function has a drawback. It does not report an error in case when the new node was not allocated.
A better approach to write the function looks the following way
int /* _Bool */ addToHead( node **head, int newData )
{
node *temp = ( node * )malloc( sizeof( node ) );
int /* _Bool */ success = temp != NULL;
if ( success )
{
temp -> data = newData;
temp -> next = *head;
*head = temp;
}
return success;
}
In this case the function can be called in a loop the following way
while ( scanf( "%i", &input ) == 1 && addToHead( &myList, input ) )
{
//...
}
i am writing a Dictionary using linked list in C, and all my functions work except my delete function, which is shown below along with all other necessary code. Every time i try to run my program as soon as it reaches a line in which it must delete a node, it gives me the error: Segmentation Fault (core dumped) which means it has something to do with the memory allocation or a null pointer i think. I know that the rest of my code works. All and any help is appreciated! :)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include"Dictionary.h"
// NodeObj
typedef struct NodeObj{
char* key;
char* value;
struct NodeObj* next;
} NodeObj;
// Node
typedef NodeObj* Node;
// newNode()
// constructor of the Node type
Node newNode(char* key, char* value)
{
Node N = malloc(sizeof(NodeObj));
assert(N!=NULL);
// if(key!=NULL && value!=NULL){
N->key = key;
N->value = value;
N->next = NULL;
// }
return(N);
}
// DictionaryObj
typedef struct DictionaryObj{
Node head;
int numItems;
} DictionaryObj;
// newDictionary()
// constructor for the Dictionary type
Dictionary newDictionary(void){
Dictionary D = malloc(sizeof(DictionaryObj));
assert(D!=NULL);
D->head = NULL;
D->numItems = 0;
return D;
}
Node findKey(Dictionary D, char*key){
Node N;
N = D->head;
while(N != NULL){
if(strcmp(N->key,key)==0){
return N;
}
N = N->next;
}
return NULL;
}
char* lookup(Dictionary D, char* k){
if(findKey(D, k)==NULL){
return NULL;
}else{
Node N;
N = findKey(D, k);
return N->value;
}
}
void delete(Dictionary D, char* k)
{
if(lookup(D,k) == NULL){
fprintf(stderr,
"KeyNotFoundException: Cannot delete non-existent key\n");
exit(EXIT_FAILURE);
}
int check = strcmp(D->head->key, k);
if(check == 1){
D->head = D->head->next;
return;
}
Node cur;
Node prev;
cur = D->head;
prev = NULL;
while( cur != NULL){
int ret1;
ret1 = strcmp(cur->key, k);
while( ret1 == 0){
prev = cur;
cur = cur->next;
}
}
prev->next = cur->next;
D->numItems--;
}
The NodeObject should store copy of the string and care for deleting it:
typedef struct Node Node;
struct Node {
Node *next;
char *key, *value;
};
Node* newNode(char* key, char* value) {
assert(key && value);
Node* node = (Node*)malloc(sizeof(Node));
assert(node);
node->next = NULL;
node->key = strdup(key);
node->value = strdup(value);
}
void delNode(Node* node) {
free(node->key);
free(node->value);
}
Consider using the original code (without that strdup) in this scenairo:
Node* prepare() {
char key_buf[20]; strcpy(key_buf, "mykey");
char val_buf[20]; strcpy(val_buf, "myval");
return newNode(key_buf, val_buf);
}
void examine(Node* node) {
printf("Node key=%s value=%s\n", node->key, node->value);
}
int main() {
examine(prepare());
}
the above code would crash because Node would have pointers to stack (in your case without that strdup), but key_buf+val_buf were only valid inside prepare() (garbage outside and therefore inside examine() - node->key points to random data).