Breadth first search suddenly crashes - c

I'm trying to implement BFS on a 400x200 grid that inputs a text file with an ordered starting pair and an ordered ending pair. I used a queue to keep track of opened nodes and an array to keep tracked of closed nodes. My program keeps crashing at random on the same input while checking for opened nodes in the queue.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
typedef struct Node Node;
typedef struct Qnode Qnode;
struct Node{
Node* up;
Node* down;
Node* left;
Node* right;
int xpos;
int ypos;
int marked;
};
struct Qnode{
Qnode* next;
Node* Gnode;
};
Qnode* front = NULL;
Qnode* rear = NULL;
int queuesize = 0;
int solutioncost = 0;
Node* closednodes[80000];
int nodesclosed = 0;
void enqueue(Node* node){
if (queuesize == 0){
rear = (Qnode*)malloc(sizeof(Qnode*));
rear->Gnode = node;
rear->next = NULL;
front = rear;
}
else{
Qnode* temp = (Qnode*)malloc(sizeof(Qnode*));
rear->next = temp;
temp->Gnode = node;
temp->next = NULL;
rear = temp;
}
queuesize++;
}
Node* dequeue(){
Qnode* temp = front;
if (queuesize == 0){
printf("Error!");
}
else{
Node* temp1 = front->Gnode;
temp = temp->next;
free(front);
front = temp;
queuesize--;
return temp1;
}
}
Node* generate(int x, int y){
printf("Generating node (%d,%d)...\n", x, y);
if ((x >0 && x <=400) && (y >0 && y <=200)){
Node* temp = (Node*)malloc(sizeof(Node));
temp->xpos = x;
temp->ypos = y;
temp->marked = 0;
temp->up = NULL;
temp->down = NULL;
temp->left = NULL;
temp->right = NULL;
return temp;
}
else{
printf("Invalid starting point! \n");
}
}
void expand(Node* node, int xend, int yend){
int flag = 0;
closednodes[nodesclosed] = node;
nodesclosed++;
dequeue();
if(node->marked == 1){
printf("already expanded");
}
else{
printf("Expanding node (%d, %d)...\n", node->xpos, node->ypos);
node->marked = 1;
if (node->xpos == xend && node->ypos == yend){
printf("Node reached!");
queuesize = 0;
return;
}
if (node->xpos-1 >0 && node->left == NULL){
int k = 0;
int j = 0;
Qnode* temp2 = front;
printf("%d", queuesize);
for(k; k<queuesize; k++){
int xx = temp2->Gnode->xpos;
int yy = temp2->Gnode->ypos;
printf("%d, %d,\n", xx, yy);
if (xx == node->xpos-1 && yy == node->ypos)
flag = 1;
temp2 = temp2->next;
}
for(j; j<nodesclosed; j++){
int xx = closednodes[j]->xpos;
int yy = closednodes[j]->ypos;
if (xx == node->xpos-1 && yy == node->ypos)
flag = 1;
}
if (flag == 0){
node->left = generate(node->xpos-1, node->ypos);
node->left->right = node->left;
enqueue(node->left);
}
else{
printf("(%d, %d) not generated.\n", node->xpos-1, node->ypos);
flag = 0;
}
}
if (node->xpos+1 <=400 && node->right ==NULL){
int k = 0;
int j = 0;
Qnode* temp2 = front;
for(k; k<queuesize; k++){
int xx = temp2->Gnode->xpos;
int yy = temp2->Gnode->ypos;
printf("%d, %d,\n", xx, yy);
if (xx == node->xpos+1 && yy == node->ypos)
flag = 1;
temp2 = temp2->next;
}
for(j; j<nodesclosed; j++){
int xx = closednodes[j]->xpos;
int yy = closednodes[j]->ypos;
if (xx == node->xpos+1 && yy == node->ypos)
flag = 1;
}
if (flag == 0){
node->right = generate(node->xpos+1, node->ypos);
node->right->left = node->right;
enqueue(node->right);
}
else{
printf("(%d, %d) not generated.\n", node->xpos+1, node->ypos);
flag = 0;
}
}
if (node->ypos+1 <=200 && node->up ==NULL){
int k = 0;
int j = 0;
Qnode* temp2 = front;
printf("%d", queuesize);
for(k; k<queuesize; k++){
int xx = temp2->Gnode->xpos;
int yy = temp2->Gnode->ypos;
if (xx == node->xpos && yy == node->ypos+1)
flag = 1;
temp2 = temp2->next;
}
for(j; j<nodesclosed; j++){
int xx = closednodes[j]->xpos;
int yy = closednodes[j]->ypos;
if (xx == node->xpos && yy == node->ypos+1)
flag = 1;
}
if (flag ==0){
node->up = generate(node->xpos, node->ypos+1);
node->up->down = node->up;
enqueue(node->up);
}
else{
printf("(%d, %d) not generated.\n", node->xpos, node->ypos+1);
flag = 0;
}
}
if (node->ypos-1 >0 && node->down ==NULL){
int k = 0;
int j = 0;
Qnode* temp2 = front;
for(k; k<queuesize; k++){
int xx = temp2->Gnode->xpos;
int yy = temp2->Gnode->ypos;
printf("%d, %d,\n", xx, yy);
if (xx == node->xpos && yy == node->ypos-1)
flag = 1;
temp2 = temp2->next;
}
for(j; j<nodesclosed; j++){
int xx = closednodes[j]->xpos;
int yy = closednodes[j]->ypos;
if (xx == node->xpos && yy == node->ypos-1)
flag = 1;
}
if (flag ==0){
node->down = generate(node->xpos, node->ypos-1);
node->down->up = node->down;
enqueue(node->down);
}
else{
printf("(%d, %d) not generated.\n", node->xpos, node->ypos-1);
flag = 0;
}
}
printf("EXPANSION ENDS\n");
return;
}
}
int main(){
int x_start, y_start, x_end, y_end;
FILE *fp;
fp = fopen("testfile.txt", "r");
if (fp == NULL)
printf("Error printing output. \n");
else
fscanf(fp, "(%d,%d)\n", &x_start, &y_start);
fscanf(fp, "(%d,%d)\n", &x_end, &y_end);
printf("Starting point is (%d, %d)\n", x_start, y_start);
printf("Ending point is (%d, %d)\n", x_end, y_end);
Node* start = generate(x_start, y_start);
enqueue(start);
while(queuesize!=0){
expand(front->Gnode, x_end, y_end);
}
fclose(fp);
}
using testfile.txt
(1,1)
(50,50)
this input will cause the program to crash at random. I am suspecting I have a problem with my queue.

In the enqueue function, you should allocate the new nodes as (Qnode*)malloc(sizeof(Qnode)) (instead of (Qnode*)). The code you wrote allocates only the size of a pointer for each struct, so any write to such an object will stomp on some other object's memory.

Related

Segmentation fault in hash table when inserting in linked list

I want to store passwords imput by user in a hash table by how strong the password is. After reading first password, it has to be inserted in the hash table and than go back for reading password. Segmentation fault occurs after first iteration.
The insertion function is basically an insertion in a linked list, what could be wrong there ?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Node{
char* str;
struct Node* next;
};
int procent(char* str){
char aux;
for(int i = 0; i < strlen(str)-1; i++){
for(int j = i+1; j < strlen(str); j++){
if(str[i] > str[j]){
aux = str[i];
str[i] = str[j];
str[j] = aux;
}
}
}
int count = 1, chr = str[0];
for(int i = 0; i < strlen(str); i++){
if(str[i] != chr){
count++;
chr = str[i];
}
}
return count;
}
int hash_function(char* str){
int len = strlen(str), index;
if(len < 5){
index = 0;
}
else if(index >= 5 && index < 8){
index = 1;
}
else if(index >= 8 && index < 12){
index = 2;
}
else{
index = 3;
}
float rap = procent(str)/strlen(str);
if(rap < 0.5 && index > 0){
index--;
}
else if(rap > 0.5 && index < 3){
index++;
}
return index;
}
void insert(struct Node** head, char* str){
printf("Error");
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
strcpy(new_node->str, str);
new_node->next = NULL;
if(*head == NULL){
*head = new_node;
return;
}
else{
struct Node* last_node = *head;
while(last_node->next != NULL){
last_node = last_node->next;
}
last_node->next = new_node;
}
}
int main(){
struct Node *H[4];
for(int i = 0; i < 4; i++){
H[i] = NULL;
}
int raspuns, rap;
char pass[20];
while(1){
printf("Mai citesti ? 1-da/0-nu: ");
scanf("%d",&raspuns);
if(raspuns == 1){
printf("Parola: ");
scanf("%s", pass);
rap = procent(pass)/strlen(pass);
insert(&H[rap], pass);
}
else{
break;
}
}
for(int i = 0; i < 4; i++){
switch(i){
case 0:{printf("Foarte slabe: "); break;}
case 1:{printf("Slabe: "); break;}
case 2:{printf("Puternice: "); break;}
case 3:{printf("Foarte puternice: "); break;}
default: break;
}
while(H[i] != NULL){
printf("%s", H[i]->str);
H[i] = H[i]->next;
}
printf("\n");
}
return 0;
}

date structure and linked list printing problem

I am trying to creat a linked list in c language,
the code compiles with no error but when I run it , it won't run.
the data structure is a task which contains the label it's number, duration , number of linked tasks which will be put in an array and a pointer to the next task.
here's my code and the test code
#include <stdio.h>
#include <stdlib.h>
typedef struct tache { //linked listes structure
char label;
int num; //task number
int dure;
int *inter;
int n; //nombre d'antécedents
struct tache * suivant;
}strTache,*pTask;
pTask creerVide(){ //créer une tache vide
return NULL;
}
pTask firstTask(int d){
//créer la première tache qui prend la durée en argument
pTask first = (strTache*)(malloc(sizeof(strTache)));
first->num = 1;
first->suivant = NULL;
first->label = 'A';
first->dure = d;
first->n = 0;
return first;
}
Bool vide(pTask t){return t==NULL;} //check if a liste of tasks is empty this is predefined in a header included in the program
pTask ajouteTask(pTask t, int d){
pTask new = (strTache*)(malloc(sizeof(strTache)));
if(vide(t)){
new = firstTask(d);
t->suivant = new;
}else
{
pTask parc = t;
while(parc->suivant != NULL){parc=parc->suivant;}
new->num = parc->num+1;
new->label = parc->label+1;
new->suivant = parc->suivant;
parc->suivant = new;
new->dure=d;
}
return new;
}
void ajouteInter(pTask p,int numero, int taille, int tab[]){
int i,j;
pTask move = p;
while(move->suivant!=NULL){
if(move->num != numero){
move=move->suivant;
}//fin if
else
{
move->inter = (int*) malloc(taille*sizeof(int));
move->n = taille;
}//fin else
}//fin while
for(i=0;i<taille;i++){
move->inter[i] = tab[i];
}//fin for
}//fin function
void affichmat2(pTask p){
int i = 0;
pTask parc = p;
while(parc!= NULL){
printf("la tache %c a %d antécédents : ",parc->label,parc->n);
for(int j=0;j<parc->n;j++){
printf("%d ",parc->inter[j]);
}
printf("\n");
parc=parc->suivant;
i++;
}
free(parc);
}
int main()
{
int b[1] = {1};
int c[2] = {1,2};
//pTask t1 = creerVide();
pTask t1 = firstTask(2);
pTask t2,t3;
t2 = ajouteTask(t1,3);
t3 = ajouteTask(t2,4);
ajouteInter(t2,2,1,b);
ajouteInter(t3,3,2,c);
affichmat2(t1);
return 0;
}
I have made some changes thanks to your advice:
the function ajoutetask which called now addtask:
,,,
pTask addTask(pTask t, int d){
pTask new;
if(vide(t)){
new = firstTask(d);
new->suivant = t;
}else
{
new = (strTache*)(malloc(sizeof(strTache)));
pTask parc = t;
while(parc->suivant != NULL){parc=parc->suivant;}
new->num = parc->num+1;
new->label = parc->label+1;
new->suivant = parc->suivant;
parc->suivant = new;
new->dure=d;
}
return new;
}
,,,
the function ajouteinter which called now add antecedent:
void addAntecedent(pTask p,int num, int size, int b[]){
pTask search = p;
while(search->num !=num){
search = search->suivant;
}
search->inter = (int*)malloc(sizeof(int)*size);
search->n = size;
for(int i = 0;i<size;i++){
search->inter[i] = b[i];
}
}
the changes to the test file :
int main (){
int b[1] = {1};
int c[2] = {1,2};
pTask t1 = firstTask(2);
pTask t2,t3;
t2 = addTask(t1,3);
t3 = addTask(t1,4);
addAntecedent(t1,2,1,b);
addAntecedent(t1,3,2,c);
affichmat2(t1);
return 0;
}
the code works properly now
the result :
la tache A a 0 antécédents :
la tache B a 1 antécédents : 1
la tache C a 2 antécédents : 1 2
For starters use English words for identifiers.
Your code does not make a sense.
Consider for example the function ajouteTask
pTask ajouteTask(pTask t, int d){
pTask new = (strTache*)(malloc(sizeof(strTache)));
if(vide(t)){
new = firstTask(d);
t->suivant = new;
//...
If the pointer t is equal to NULL (that is when the function vide returns 1) then 1) the function invokes undefined behavior due to this statement
t->suivant = new;
and 2) it produces a memory leak because at first a memory was allocated and its address was assigned to the pointer new
pTask new = (strTache*)(malloc(sizeof(strTache)));
and then the pointer was reassigned
new = firstTask(d);
Or within the function ajouteInter you have an infinite while loop if move->num is equal to numero
void ajouteInter(pTask p,int numero, int taille, int tab[]){
int i,j;
pTask move = p;
while(move->suivant!=NULL){
if(move->num != numero){
move=move->suivant;
}//fin if
else
{
move->inter = (int*) malloc(taille*sizeof(int));
move->n = taille;
}//fin else
}//fin while
//...
So what you need is to rework your code and if there will be problems ask a new question.
Click here
https://uniblogsp.blogspot.com/2022/05/link-list-implementation-in-c-insertion.html
#include <stdio.h>
#include <stdlib.h>
typedef struct intnode
{
int data;
struct intnode *next;
} intnode;
intnode *create(int n)
{
intnode *head, *q, *newnode;
head = (intnode *)malloc(sizeof(intnode));
scanf("%d", &head->data);
head->next = NULL;
q = head;
for (int i = 0; i < n - 1; i++)
{
newnode = (intnode *)malloc(sizeof(intnode));
scanf("%d", &newnode->data);
newnode->next = NULL;
q->next = newnode;
q = newnode;
}
return head;
}
void printList(intnode *head)
{
intnode *temp;
temp = head;
while (head != NULL)
{
printf("%d", head->data);
head = head->next;
printf("\n");
}
head = temp;
}
void insertList(intnode *head, int i, intnode *t)
{
intnode *r, *x;
if (i == 0)
{
t->next = head;
head = t;
return;
}
r = head;
for (int j = 1; (j < i - 1) && (r != NULL); j++)
{
r = r->next;
}
if ((r == NULL) && (i > 0))
{
return;
}
x = r;
t->next = x->next;
x->next = t;
return;
}
void deleteList(intnode *head, int i)
{
intnode *y, *x;
y = head;
if (i == 0)
{
head = head->next;
free(y);
return;
}
x = y->next;
for (int j = 1; (j < i) && (x != NULL); i++)
{
y = x;
x = x->next;
}
if ((x == NULL) && (i > 0))
{
return;
}
y->next = x->next;
x->next = NULL;
free(x);
return;
}
int main()
{
int n, l;
printf("Enter the no of nodes: \n");
scanf("%d", &n);
printf("Enter the elements of nodes: \n");
intnode *p = create(n);
printf("Nodes are: \n");
printList(p);
printf("If you want to insert node then press 1 and in case of delete node press 0 : \n");
int ans;
scanf("%d", &ans);
if (ans == 1)
{
printf("In what positiomn you want to insert the node ??\n");
scanf("%d", &l);
intnode *a;
a = (intnode *)malloc(sizeof(intnode));
printf("Enter the node data :\n");
scanf("%d", &a->data);
a->next = NULL;
insertList(p, l, a);
printf("After insertion the list is : \n");
printList(p);
}
else
{
printf("In what positiomn you want to delete the node ??\n");
scanf("%d", &l);
deleteList(p, l);
printf("After deletion the list is : \n");
printList(p);
}
return 0;
}

Preorder Postorder Tree Traversal when RSON and LSON are given

If you input this
1111010000000 //LSON
GERLWIDAKONTH //DATA
1101101000110 //RSON
it should output the Preorder and Postorder of the given tree.
THE PROBLEM IS: MY PROGRAM DOESN'T PRINT THE CORRECT POSTORDER AND I CAN'T FIGURE OUT WHY. I hope you could help me. The Preorder is already correct but it is okay with me if you want to add anything to improve my codes. THANK YOU!:D
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 5
#define CASE 3
#define N 100
struct node{
char data;
struct node* llink;
struct node* rlink;
int tag;
};
typedef struct node Node;
typedef Node* NodePtr;
void twoPreorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o);
void threePreorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o);
void twoPostorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o);
void threePostorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o);
void printSequence(char *array[3], int size){
int i;
printf("LTAG: ");
for(i = 0; i < size; i++)
printf("%c", array[0][i]);
printf("\nDATA: ");
for(i = 0; i < size; i++)
printf("%c", array[1][i]);
printf("\nRTAG: ");
for(i = 0; i < size; i++)
printf("%c", array[2][i]);
printf("\n\n");
}
void onePreorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
printf("%c", (*b)->data);
*counter = *counter+1;
int count = *counter;
int n = *size;
//printf("counter=%d\tsize=%d\n", count, n);
if(count == n){
return;
}
*o = (*b)->llink;
if(*o != NULL){
(*b)->llink = *a;
*a = *b;
*b = *o;
onePreorder(counter, size, a, b, o);
}
//printf("o NULL\n");
else{
twoPreorder(counter, size, a, b, o);
}
}
void twoPreorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
*o = (*b)->rlink;
if(*o != NULL){
(*b)->rlink = *a;
(*b)->tag = 1;
*a = *b;
*b = *o;
onePreorder(counter, size, a, b, o);
}
//printf("o NULL\n");
threePreorder(counter, size, a, b, o);
}
void threePreorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
//printf("a = %c\n", (*a)->data);
if((*a) == NULL)
return;
else{
if((*a)->tag == 0){
*o = (*a)->llink;
(*a)->llink = *b;
*b = *a;
*a = *o;
twoPreorder(counter, size, a, b, o);
}
else{
*o = (*a)->rlink;
(*a)->rlink = *b;
(*a)->tag = 0;
*b = *a;
*a = *o;
threePreorder(counter, size, a, b, o);
}
}
}
void preorder1(int size, NodePtr root){
printf("Preorder:\t");
if(root == NULL)
return;
NodePtr a = NULL;
NodePtr b = malloc(sizeof(Node));
b = root;
NodePtr o = NULL;
int i = 0;
onePreorder(&i, &size, &a, &b, &o);
printf("\n");
}
void onePostorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
*o = (*b)->llink;
if(*o != NULL){
(*b)->llink = *a;
*a = *b;
*b = *o;
onePostorder(counter, size, a, b, o);
}
else{
twoPostorder(counter, size, a, b, o);
}
}
void twoPostorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
*o = (*b)->rlink;
if(*o != NULL){
printf("%c", (*b)->data);
(*b)->rlink = *a;
(*b)->tag = 1;
*a = *b;
*b = *o;
onePostorder(counter, size, a, b, o);
}
else{
printf("%c", (*b)->data);
threePostorder(counter, size, a, b, o);
}
}
void threePostorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
//printf("a = %c\n", (*a)->data);
if((*a) == NULL)
return;
else{
if((*a)->tag == 0){
*o = (*a)->llink;
(*a)->llink = *b;
*b = *a;
printf("%c", (*b)->data);
*counter++;
int i = *counter;
int n = *size;
if(i == n)
return;
*a = *o;
twoPostorder(counter, size, a, b, o);
}
else{
*o = (*a)->rlink;
(*a)->rlink = *b;
(*a)->tag = 0;
*b = *a;
printf("%c", (*b)->data);
*counter++;
int i = *counter;
int n = *size;
if(i == n)
return;
*a = *o;
threePostorder(counter, size, a, b, o);
}
}
}
void postorder1(int size, NodePtr root){
if(root == NULL)
return;
printf("Postorder:\t");
NodePtr a = NULL;
NodePtr b = malloc(sizeof(Node));
b = root;
NodePtr o = NULL;
int i = 0;
onePostorder(&i, &size, &a, &b, &o);
printf("%c", root->data);
printf("\n");
}
NodePtr createNode(char val){
NodePtr x = malloc(sizeof(Node));
if(x == NULL){
printf("Overflow\n");
}
else{
x->data = val;
x->llink = NULL;
x->rlink = NULL;
x->tag = 0;
}
return x;
}
int isValidSequence(char *array[3], int size){
int ones = 0;
int zeroes = 0;
int i;
if(array[2][size-1] == '1'){
printf("INVALID SEQUENCES!\nLast token not the last sibling\n");
return -1;
}
for(i = 0; i < size; i++){
if(array[0][i] == '1'){
ones++;
if(ones >= 1)
array[0][i] = ones + 48;
//printf("array[0][i] = %c\n", array[0][i]);
}
if(array[2][i] == '0')
zeroes++;
}
//printf("1: %d\t0: %d\n", ones, zeroes);
if((zeroes - 1) != ones){
printf("INVALID SEQUENCES!\nUnbalanced number of ones in LTAG and zeroesin RTAG sequence (excluding last token).\n");
return -1;
}
else if((zeroes - 1) == ones)
return 1;
}
int getIndex(char value, char *array[3], int size){
int zero = 0;
int i;
for(i = 0; i < size; i++){
if(array[2][i] == '0'){
zero++;
//printf("index: %d\tvalue: %d\n", i, (value)-48);
if(zero + 48 == value){
//printf("index: %d\n", i+1);
return (i + 1);
}
}
}
return -1;
}
int firstNotDone(int doneLson[], int doneRson[], int size){
int i;
for(i = 0; i < size; i++)
if((doneLson[i] < 1) || (doneRson[i] < 1))
return i;
return -1;
}
void createTree(int size, char *array[3], NodePtr *root){
int i;
int currentIndex = 0;
int lsonIndex;
int isDoneLson[size];
int isDoneRson[size];
NodePtr node[size];
for(i = 0; i < size; i++){
isDoneLson[i] = 0;
isDoneRson[i] = 0;
node[i] = createNode(array[1][i]);
}
//int k = 0;
do{
while((array[2][currentIndex] == '1') && (isDoneRson[currentIndex] < 1)){
//printf("has siblings\n");
node[currentIndex]->rlink = node[currentIndex + 1];
isDoneRson[currentIndex]++;
currentIndex++;
}
isDoneRson[currentIndex]++;
//printf("current: %c\tcurrentIndex = %d\tlson = %d\trson = %d\n", array[1][currentIndex], currentIndex, isDoneLson[currentIndex], isDoneRson[currentIndex]);
//test siblings
NodePtr newNode = malloc(sizeof(Node));
newNode = node[currentIndex];
while(newNode != NULL){
//printf("seq: %c\n", newNode->data);
newNode = newNode->rlink;
}
currentIndex = firstNotDone(isDoneLson, isDoneRson, size);
//printf("current: %c\tcurrentIndex = %d\tlson = %d\trson = %d\n", array[1][currentIndex], currentIndex, isDoneLson[currentIndex], isDoneRson[currentIndex]);
if(array[0][currentIndex] != '0'){
//printf("has lson\n");
lsonIndex = getIndex(array[0][currentIndex], array, size);
//printf("lson of %c is %c\n", array[1][currentIndex], array[1][lsonIndex]);
node[currentIndex]->llink = node[lsonIndex];
}
isDoneLson[currentIndex]++;
//printf("current: %c\tcurrentIndex = %d\tlson = %d\trson = %d\n", array[1][currentIndex], currentIndex, isDoneLson[currentIndex], isDoneRson[currentIndex]);
isDoneLson[currentIndex]++;
currentIndex = firstNotDone(isDoneLson, isDoneRson, size);;
//printf("current: %c\tcurrentIndex = %d\tlson = %d\trson = %d\n", array[1][currentIndex], currentIndex, isDoneLson[currentIndex], isDoneRson[currentIndex]);
//k++;
}while(currentIndex != -1);
/*
for(i = 0; i < size; i++){
printf("Node[%d]: %c\t", i, node[i]->data);
if(node[i]->llink != NULL)
printf("llink: %c\t", node[i]->llink->data);
if(node[i]->rlink != NULL)
printf("rlink: %c\t", node[i]->rlink->data);
printf("\n");
}
**/
root = &node[0];
preorder1(size, node[0]);
postorder1(size, node[0]);
printf("\n");
}
void file(FILE *ptr, char *array[3], NodePtr *root){
char c;
int i = 0;
int j = 0;
int initSize = N;
int k;
int n;
array[0] = malloc(initSize);
do{
c = fgetc(ptr);
if(c == '\n'){
n = j;
j = 0;
break;
}
else{
if(j == (initSize - 1)){
initSize = initSize + N;
array[0] = realloc(array[0], initSize);
}
array[0][j] = c;
j++;
}
}while(1);
array[1] = malloc(n);
fscanf(ptr, "%s", array[1]);
array[2] = malloc(n);
fscanf(ptr, "%s", array[2]);
//print array
printSequence(array, n);
int isValid = isValidSequence(array, n);
if(isValid == 1){
createTree(n, array, root);
}
c = fgetc(ptr);
if(c == EOF){
printf("END\n");
fclose(ptr);
}
else{
c = fgetc(ptr);
file(ptr, array, root);
fclose(ptr);
}
}
void insertLson(NodePtr *father, NodePtr lson){
NodePtr x = malloc(sizeof(Node));
NodePtr *y;
x = (*father)->llink;
while(x != NULL){
x = x->llink;
}
y = &x;
x = lson;
printf("x = %c\n", x->data);
}
void type(char *array[3], NodePtr *root){
int lines = 0;
char c = getchar();
int n = 0;
int size;
int initSize = N;
array[0] = malloc(initSize);
c = getchar();
do{
if(c == '\n'){
size = n;
break;
}
else{
if(n == (initSize - 1)){
initSize = initSize + N;
array[0] = realloc(array[0], initSize);
}
array[0][n] = c;
n++;
}
c = getchar();
}while(1);
array[1] = malloc(size);
array[2] = malloc(size);
scanf("%s", array[1]);
scanf("%s", array[2]);
printSequence(array, n);
// printf("%s\t%s\t%s\n", array[0], array[1], array[2]);
// printf("%sdafi\n", array[0]);
int isValid = isValidSequence(array, size);
if(isValid == 1){
//printSequence(array, n);
//printf("isvalid\nsize: %d\n", n);
createTree(n, array, root);
}
c = getchar();
if(c == EOF){
printf("END\n");
return;
}
else{
c = getchar();
type(array, root);
}
}
int tree(){
NodePtr *root = NULL;
char *array[3];
int *size;
char filename[50];
int choice;
printf("Choose input:\n1. Keyboard\n2. File\n");
scanf("%d", &choice);
switch(choice){
case 1:
printf("Type input\n");
type(array, root);
break;
case 2:
printf("Type filename\n");
scanf("%s", filename);
FILE* ptr = fopen(filename, "r");
file(ptr, array, root);
break;
default:
printf("Invalid choice\n");
break;
}
}
int main(void){
tree();
return 0;
}

Btree deletion code [duplicate]

Can anyone please help in removing this segmentation fault. I am working on this code for a week still unable to debug this. This code is a Btree implementation. The insertion part is working properly but there is an segmentation fault in deletion. I am unable to debug it, can anyone please help?
I have given the input based on this link (have converted alphabet value to ASCII value)
http://cis.stvincent.edu/html/tutorials/swd/btree/btree.html
When I delete the first H (equivalent ASCII value) it works properly, but when I delete T (equivalent ASCII value) I will get a segmentation fault.
#include<stdio.h>
#include<stdlib.h>
#define M 5
struct node{
int n; /* n < M No. of keys in node will always less than order of B
tree */
int keys[M-1]; /*array of keys*/
struct node *p[M]; /* (n+1 pointers will be in use) */
}*root=NULL;
enum KeyStatus { Duplicate,SearchFailure,Success,InsertIt,LessKeys };
void insert(int key);
void display(struct node *root,int);
void DelNode(int x);
void search(int x);
enum KeyStatus ins(struct node *r, int x, int* y, struct node** u);
int searchPos(int x,int *key_arr, int n);
enum KeyStatus del(struct node *r, int x);
int input_array[20]= {65,67,71,78,72,69,75,81,77,70,87,76,84,90,68,80,82,88,89,83};
int main()
{
int choice, i,key = 11;
printf("Creation of B tree for node %d\n",M);
while(1)
{
printf("1.Insert\n");
printf("2.Delete\n");
printf("3.Search\n");
printf("4.Display\n");
printf("5.Quit\n");
printf("Enter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
//printf("Enter the key : ");
//scanf("%d",&key);
//for(i=0;i<20;i++)
for(i=0;i<20;i++)
{
key = input_array[i];
insert(key);
}
//insert(key++);
//insert(key);
break;
case 2:
printf("Enter the key : ");
scanf("%d",&key);
DelNode(key);
break;
case 3:
printf("Enter the key : ");
scanf("%d",&key);
search(key);
break;
case 4:
printf("Btree is :\n");
display(root,0);
break;
case 5:
exit(1);
default:
printf("Wrong choice\n");
break;
}/*End of switch*/
}/*End of while*/
return 0;
}/*End of main()*/
void insert(int key)
{
struct node *newnode;
int upKey;
enum KeyStatus value;
value = ins(root, key, &upKey, &newnode);
if (value == Duplicate)
printf("Key already available\n");
if (value == InsertIt)
{
struct node *uproot = root;
root=malloc(sizeof(struct node));
root->n = 1;
root->keys[0] = upKey;
root->p[0] = uproot;
root->p[1] = newnode;
}/*End of if */
}/*End of insert()*/
enum KeyStatus ins(struct node *ptr, int key, int *upKey,struct node **newnode)
{
struct node *newPtr, *lastPtr;
int pos, i, n,splitPos;
int newKey, lastKey;
enum KeyStatus value;
if (ptr == NULL)
{
*newnode = NULL;
*upKey = key;
return InsertIt;
}
n = ptr->n;
pos = searchPos(key, ptr->keys, n);
if (pos < n && key == ptr->keys[pos])
return Duplicate;
value = ins(ptr->p[pos], key, &newKey, &newPtr);
if (value != InsertIt)
return value;
/*If keys in node is less than M-1 where M is order of B tree*/
if (n < M - 1)
{
pos = searchPos(newKey, ptr->keys, n);
/*Shifting the key and pointer right for inserting the new key*/
for (i=n; i>pos; i--)
{
ptr->keys[i] = ptr->keys[i-1];
ptr->p[i+1] = ptr->p[i];
}
/*Key is inserted at exact location*/
ptr->keys[pos] = newKey;
ptr->p[pos+1] = newPtr;
++ptr->n; /*incrementing the number of keys in node*/
return Success;
}/*End of if */
/*If keys in nodes are maximum and position of node to be inserted is
last*/
if (pos == M - 1)
{
lastKey = newKey;
lastPtr = newPtr;
}
else /*If keys in node are maximum and position of node to be inserted
is not last*/
{
lastKey = ptr->keys[M-2];
lastPtr = ptr->p[M-1];
for (i=M-2; i>pos; i--)
{
ptr->keys[i] = ptr->keys[i-1];
ptr->p[i+1] = ptr->p[i];
}
ptr->keys[pos] = newKey;
ptr->p[pos+1] = newPtr;
}
splitPos = (M - 1)/2;
(*upKey) = ptr->keys[splitPos];
(*newnode)=malloc(sizeof(struct node));/*Right node after split*/
ptr->n = splitPos; /*No. of keys for left splitted node*/
(*newnode)->n = M-1-splitPos;/*No. of keys for right splitted node*/
for (i=0; i < (*newnode)->n; i++)
{
(*newnode)->p[i] = ptr->p[i + splitPos + 1];
if(i < (*newnode)->n - 1)
(*newnode)->keys[i] = ptr->keys[i + splitPos + 1];
else
(*newnode)->keys[i] = lastKey;
}
(*newnode)->p[(*newnode)->n] = lastPtr;
return InsertIt;
}/*End of ins()*/
void display(struct node *ptr, int blanks)
{
if (ptr)
{
int i;
for(i=1;i<=blanks;i++)
printf(" ");
for (i=0; i < ptr->n; i++)
printf("%d ",ptr->keys[i]);
printf("\n");
for (i=0; i <= ptr->n; i++)
display(ptr->p[i], blanks+10);
}/*End of if*/
}/*End of display()*/
void search(int key)
{
int pos, i, n;
struct node *ptr = root;
printf("Search path:\n");
while (ptr)
{
n = ptr->n;
for (i=0; i < ptr->n; i++)
printf(" %d",ptr->keys[i]);
printf("\n");
pos = searchPos(key, ptr->keys, n);
if (pos < n && key == ptr->keys[pos])
{
printf("Key %d found in position %d of last dispalyednode\n",key,i);
return;
}
ptr = ptr->p[pos];
}
printf("Key %d is not available\n",key);
}/*End of search()*/
int searchPos(int key, int *key_arr, int n)
{
int pos=0;
while (pos < n && key > key_arr[pos])
pos++;
return pos;
}/*End of searchPos()*/
void DelNode(int key)
{
struct node *uproot;
enum KeyStatus value;
value = del(root,key);
switch (value)
{
case SearchFailure:
printf("Key %d is not available\n",key);
break;
case LessKeys:
uproot = root;
root = root->p[0];
free(uproot);
break;
}/*End of switch*/
}/*End of delnode()*/
enum KeyStatus del(struct node *ptr, int key)
{
int pos, i, pivot, n ,min;
int *key_arr;
enum KeyStatus value;
struct node **p,*lptr,*rptr;
if (ptr == NULL)
return SearchFailure;
/*Assigns values of node*/
n=ptr->n;
key_arr = ptr->keys;
p = ptr->p;
min = (M - 1)/2;/*Minimum number of keys*/
pos = searchPos(key, key_arr, n);
if (p[0] == NULL)
{
if (pos == n || key < key_arr[pos])
return SearchFailure;
/*Shift keys and pointers left*/
for (i=pos+1; i < n; i++)
{
key_arr[i-1] = key_arr[i];
p[i] = p[i+1];
}
return --ptr->n >= (ptr==root ? 1 : min) ? Success : LessKeys;
}/*End of if */
if (pos < n && key == key_arr[pos])
{
struct node *qp = p[pos], *qp1;
int nkey;
while(1)
{
nkey = qp->n;
qp1 = qp->p[nkey];
if (qp1 == NULL)
break;
qp = qp1;
}/*End of while*/
key_arr[pos] = qp->keys[nkey-1];
qp->keys[nkey - 1] = key;
}/*End of if */
value = del(p[pos], key);
if (value != LessKeys)
return value;
if (pos > 0 && p[pos-1]->n > min)
{
pivot = pos - 1; /*pivot for left and right node*/
lptr = p[pivot];
rptr = p[pos];
/*Assigns values for right node*/
rptr->p[rptr->n + 1] = rptr->p[rptr->n];
for (i=rptr->n; i>0; i--)
{
rptr->keys[i] = rptr->keys[i-1];
rptr->p[i] = rptr->p[i-1];
}
rptr->n++;
rptr->keys[0] = key_arr[pivot];
rptr->p[0] = lptr->p[lptr->n];
key_arr[pivot] = lptr->keys[--lptr->n];
return Success;
}/*End of if */
if (pos > min)
{
pivot = pos; /*pivot for left and right node*/
lptr = p[pivot];
rptr = p[pivot+1];
/*Assigns values for left node*/
lptr->keys[lptr->n] = key_arr[pivot];
lptr->p[lptr->n + 1] = rptr->p[0];
key_arr[pivot] = rptr->keys[0];
lptr->n++;
rptr->n--;
for (i=0; i < rptr->n; i++)
{
rptr->keys[i] = rptr->keys[i+1];
rptr->p[i] = rptr->p[i+1];
}/*End of for*/
rptr->p[rptr->n] = rptr->p[rptr->n + 1];
return Success;
}/*End of if */
if(pos == n)
pivot = pos-1;
else
pivot = pos;
lptr = p[pivot];
rptr = p[pivot+1];
/*merge right node with left node*/
lptr->keys[lptr->n] = key_arr[pivot];
lptr->p[lptr->n + 1] = rptr->p[0];
for (i=0; i < rptr->n; i++)
{
lptr->keys[lptr->n + 1 + i] = rptr->keys[i];
lptr->p[lptr->n + 2 + i] = rptr->p[i+1];
}
lptr->n = lptr->n + rptr->n +1;
free(rptr); /*Remove right node*/
for (i=pos+1; i < n; i++)
{
key_arr[i-1] = key_arr[i];
p[i] = p[i+1];
}
return --ptr->n >= (ptr == root ? 1 : min) ? Success : LessKeys;
}/*End of del()*/
What could be the problem?
Without knowing exactly how this should work I can say that you write outside of the p vector on
for (i=0; i < rptr->n; i++)
{
lptr->keys[lptr->n + 1 + i] = rptr->keys[i];
// When you delete key 84, rptr->n is 4 at one point which takes you outside
// p[M]
lptr->p[lptr->n + 2 + i] = rptr->p[i+1];
}
Valgrind is a good tool to use, and I found this problem by valgrind -v --leak-check=full <your executable>

Segmentation fault in btree implementation

Can anyone please help in removing this segmentation fault. I am working on this code for a week still unable to debug this. This code is a Btree implementation. The insertion part is working properly but there is an segmentation fault in deletion. I am unable to debug it, can anyone please help?
I have given the input based on this link (have converted alphabet value to ASCII value)
http://cis.stvincent.edu/html/tutorials/swd/btree/btree.html
When I delete the first H (equivalent ASCII value) it works properly, but when I delete T (equivalent ASCII value) I will get a segmentation fault.
#include<stdio.h>
#include<stdlib.h>
#define M 5
struct node{
int n; /* n < M No. of keys in node will always less than order of B
tree */
int keys[M-1]; /*array of keys*/
struct node *p[M]; /* (n+1 pointers will be in use) */
}*root=NULL;
enum KeyStatus { Duplicate,SearchFailure,Success,InsertIt,LessKeys };
void insert(int key);
void display(struct node *root,int);
void DelNode(int x);
void search(int x);
enum KeyStatus ins(struct node *r, int x, int* y, struct node** u);
int searchPos(int x,int *key_arr, int n);
enum KeyStatus del(struct node *r, int x);
int input_array[20]= {65,67,71,78,72,69,75,81,77,70,87,76,84,90,68,80,82,88,89,83};
int main()
{
int choice, i,key = 11;
printf("Creation of B tree for node %d\n",M);
while(1)
{
printf("1.Insert\n");
printf("2.Delete\n");
printf("3.Search\n");
printf("4.Display\n");
printf("5.Quit\n");
printf("Enter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
//printf("Enter the key : ");
//scanf("%d",&key);
//for(i=0;i<20;i++)
for(i=0;i<20;i++)
{
key = input_array[i];
insert(key);
}
//insert(key++);
//insert(key);
break;
case 2:
printf("Enter the key : ");
scanf("%d",&key);
DelNode(key);
break;
case 3:
printf("Enter the key : ");
scanf("%d",&key);
search(key);
break;
case 4:
printf("Btree is :\n");
display(root,0);
break;
case 5:
exit(1);
default:
printf("Wrong choice\n");
break;
}/*End of switch*/
}/*End of while*/
return 0;
}/*End of main()*/
void insert(int key)
{
struct node *newnode;
int upKey;
enum KeyStatus value;
value = ins(root, key, &upKey, &newnode);
if (value == Duplicate)
printf("Key already available\n");
if (value == InsertIt)
{
struct node *uproot = root;
root=malloc(sizeof(struct node));
root->n = 1;
root->keys[0] = upKey;
root->p[0] = uproot;
root->p[1] = newnode;
}/*End of if */
}/*End of insert()*/
enum KeyStatus ins(struct node *ptr, int key, int *upKey,struct node **newnode)
{
struct node *newPtr, *lastPtr;
int pos, i, n,splitPos;
int newKey, lastKey;
enum KeyStatus value;
if (ptr == NULL)
{
*newnode = NULL;
*upKey = key;
return InsertIt;
}
n = ptr->n;
pos = searchPos(key, ptr->keys, n);
if (pos < n && key == ptr->keys[pos])
return Duplicate;
value = ins(ptr->p[pos], key, &newKey, &newPtr);
if (value != InsertIt)
return value;
/*If keys in node is less than M-1 where M is order of B tree*/
if (n < M - 1)
{
pos = searchPos(newKey, ptr->keys, n);
/*Shifting the key and pointer right for inserting the new key*/
for (i=n; i>pos; i--)
{
ptr->keys[i] = ptr->keys[i-1];
ptr->p[i+1] = ptr->p[i];
}
/*Key is inserted at exact location*/
ptr->keys[pos] = newKey;
ptr->p[pos+1] = newPtr;
++ptr->n; /*incrementing the number of keys in node*/
return Success;
}/*End of if */
/*If keys in nodes are maximum and position of node to be inserted is
last*/
if (pos == M - 1)
{
lastKey = newKey;
lastPtr = newPtr;
}
else /*If keys in node are maximum and position of node to be inserted
is not last*/
{
lastKey = ptr->keys[M-2];
lastPtr = ptr->p[M-1];
for (i=M-2; i>pos; i--)
{
ptr->keys[i] = ptr->keys[i-1];
ptr->p[i+1] = ptr->p[i];
}
ptr->keys[pos] = newKey;
ptr->p[pos+1] = newPtr;
}
splitPos = (M - 1)/2;
(*upKey) = ptr->keys[splitPos];
(*newnode)=malloc(sizeof(struct node));/*Right node after split*/
ptr->n = splitPos; /*No. of keys for left splitted node*/
(*newnode)->n = M-1-splitPos;/*No. of keys for right splitted node*/
for (i=0; i < (*newnode)->n; i++)
{
(*newnode)->p[i] = ptr->p[i + splitPos + 1];
if(i < (*newnode)->n - 1)
(*newnode)->keys[i] = ptr->keys[i + splitPos + 1];
else
(*newnode)->keys[i] = lastKey;
}
(*newnode)->p[(*newnode)->n] = lastPtr;
return InsertIt;
}/*End of ins()*/
void display(struct node *ptr, int blanks)
{
if (ptr)
{
int i;
for(i=1;i<=blanks;i++)
printf(" ");
for (i=0; i < ptr->n; i++)
printf("%d ",ptr->keys[i]);
printf("\n");
for (i=0; i <= ptr->n; i++)
display(ptr->p[i], blanks+10);
}/*End of if*/
}/*End of display()*/
void search(int key)
{
int pos, i, n;
struct node *ptr = root;
printf("Search path:\n");
while (ptr)
{
n = ptr->n;
for (i=0; i < ptr->n; i++)
printf(" %d",ptr->keys[i]);
printf("\n");
pos = searchPos(key, ptr->keys, n);
if (pos < n && key == ptr->keys[pos])
{
printf("Key %d found in position %d of last dispalyednode\n",key,i);
return;
}
ptr = ptr->p[pos];
}
printf("Key %d is not available\n",key);
}/*End of search()*/
int searchPos(int key, int *key_arr, int n)
{
int pos=0;
while (pos < n && key > key_arr[pos])
pos++;
return pos;
}/*End of searchPos()*/
void DelNode(int key)
{
struct node *uproot;
enum KeyStatus value;
value = del(root,key);
switch (value)
{
case SearchFailure:
printf("Key %d is not available\n",key);
break;
case LessKeys:
uproot = root;
root = root->p[0];
free(uproot);
break;
}/*End of switch*/
}/*End of delnode()*/
enum KeyStatus del(struct node *ptr, int key)
{
int pos, i, pivot, n ,min;
int *key_arr;
enum KeyStatus value;
struct node **p,*lptr,*rptr;
if (ptr == NULL)
return SearchFailure;
/*Assigns values of node*/
n=ptr->n;
key_arr = ptr->keys;
p = ptr->p;
min = (M - 1)/2;/*Minimum number of keys*/
pos = searchPos(key, key_arr, n);
if (p[0] == NULL)
{
if (pos == n || key < key_arr[pos])
return SearchFailure;
/*Shift keys and pointers left*/
for (i=pos+1; i < n; i++)
{
key_arr[i-1] = key_arr[i];
p[i] = p[i+1];
}
return --ptr->n >= (ptr==root ? 1 : min) ? Success : LessKeys;
}/*End of if */
if (pos < n && key == key_arr[pos])
{
struct node *qp = p[pos], *qp1;
int nkey;
while(1)
{
nkey = qp->n;
qp1 = qp->p[nkey];
if (qp1 == NULL)
break;
qp = qp1;
}/*End of while*/
key_arr[pos] = qp->keys[nkey-1];
qp->keys[nkey - 1] = key;
}/*End of if */
value = del(p[pos], key);
if (value != LessKeys)
return value;
if (pos > 0 && p[pos-1]->n > min)
{
pivot = pos - 1; /*pivot for left and right node*/
lptr = p[pivot];
rptr = p[pos];
/*Assigns values for right node*/
rptr->p[rptr->n + 1] = rptr->p[rptr->n];
for (i=rptr->n; i>0; i--)
{
rptr->keys[i] = rptr->keys[i-1];
rptr->p[i] = rptr->p[i-1];
}
rptr->n++;
rptr->keys[0] = key_arr[pivot];
rptr->p[0] = lptr->p[lptr->n];
key_arr[pivot] = lptr->keys[--lptr->n];
return Success;
}/*End of if */
if (pos > min)
{
pivot = pos; /*pivot for left and right node*/
lptr = p[pivot];
rptr = p[pivot+1];
/*Assigns values for left node*/
lptr->keys[lptr->n] = key_arr[pivot];
lptr->p[lptr->n + 1] = rptr->p[0];
key_arr[pivot] = rptr->keys[0];
lptr->n++;
rptr->n--;
for (i=0; i < rptr->n; i++)
{
rptr->keys[i] = rptr->keys[i+1];
rptr->p[i] = rptr->p[i+1];
}/*End of for*/
rptr->p[rptr->n] = rptr->p[rptr->n + 1];
return Success;
}/*End of if */
if(pos == n)
pivot = pos-1;
else
pivot = pos;
lptr = p[pivot];
rptr = p[pivot+1];
/*merge right node with left node*/
lptr->keys[lptr->n] = key_arr[pivot];
lptr->p[lptr->n + 1] = rptr->p[0];
for (i=0; i < rptr->n; i++)
{
lptr->keys[lptr->n + 1 + i] = rptr->keys[i];
lptr->p[lptr->n + 2 + i] = rptr->p[i+1];
}
lptr->n = lptr->n + rptr->n +1;
free(rptr); /*Remove right node*/
for (i=pos+1; i < n; i++)
{
key_arr[i-1] = key_arr[i];
p[i] = p[i+1];
}
return --ptr->n >= (ptr == root ? 1 : min) ? Success : LessKeys;
}/*End of del()*/
What could be the problem?
Without knowing exactly how this should work I can say that you write outside of the p vector on
for (i=0; i < rptr->n; i++)
{
lptr->keys[lptr->n + 1 + i] = rptr->keys[i];
// When you delete key 84, rptr->n is 4 at one point which takes you outside
// p[M]
lptr->p[lptr->n + 2 + i] = rptr->p[i+1];
}
Valgrind is a good tool to use, and I found this problem by valgrind -v --leak-check=full <your executable>

Resources