C - Popping last item from linked lists - c

I am learning linked lists and they are causing me a lot of troubles.
I am calling the function with this call:
pop(&list);
ANd here's the code:
void pop(NODE** first) {
if(*first != NULL && first!= NULL){
NODE* ptr = *first;
while(ptr->next->next != NULL){
ptr = ptr->next;
}
free(ptr->next);
ptr->next = NULL;
}
It's also causing memory leak error even if I call it single time..
When calling this function multiple times, there are more memory leak errors.
Thanks in advance, Mimpopo.
EDIT: Definition of NODE
typedef struct node {
int data;
struct node *next;
} NODE;
The full CODE:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} NODE;
NODE* insert(NODE *first, int n){
// create new node
NODE* new = (NODE*)malloc(sizeof(NODE));
new->data = n;
new->next = NULL;
// if first is NULL, this will be the first
if(first == NULL)
return new;
// otherwise, place it correctly
NODE* ptr = first;
// check inserting at the begining
if(ptr->data > new->data){
new->next = ptr;
return new;
}
// insert in the middle
while(ptr->next != NULL){
if(ptr->next->data > n && ptr->data < n){
new->next = ptr->next;
ptr->next = new;
break;
}
ptr = ptr->next;
}
// insert at the end of list
if(ptr->next == NULL){
ptr->next = new;
}
return first;
}
void traverse(NODE *first){
NODE* ptr = first;
while(ptr != NULL){
printf("%d\n", ptr->data);
ptr = ptr->next;
}
}
NODE* search(NODE *first, int n){
NODE* ptr = first;
while(ptr != NULL){
if(ptr->data == n){
printf("FOUND %d\n!", n);
return ptr;
}
ptr = ptr->next;
}
}
int main(){
NODE* first = NULL;
NODE* this = NULL;
first = insert(first, 7);
first = insert(first, 10);
first = insert(first, 11);
first = insert(first, 1);
first = insert(first, 3);
first = insert(first, 5);
first = insert(first, 22);
first = insert(first, 23);
first = insert(first, 24);
first = insert(first, 125);
pop(&first);
}

I have not looked through all your code but as for the function then it can be written the following way
void pop( NODE ** first )
{
if ( *first != NULL )
{
NODE *prev = NULL;
NODE *current = *first;
while ( current->next )
{
prev = current;
current = current->next;
}
if ( prev != NULL ) prev->next = current->next;
else ( *first = NULL );
free( current );
}
}
As for your function implementation then it contains many errors. For example in this statement
if(*first != NULL && first!= NULL){
you shall swap the first and the second comparisons. That is the condition shall look like
if(first != NULL && *first!= NULL){
In this statement
while(ptr->next->next != NULL){
You have to be sure that ptr->nextis not equal to NULL.
Also you do not check whether the deleted node is the first node of the list.
Take into account that function insert is also wrong. You consider only one condition in this code snippet
while(ptr->next != NULL){
if(ptr->next->data > n && ptr->data < n){
new->next = ptr->next;
ptr->next = new;
break;
}
ptr = ptr->next;
}
However it can be that for example
ptr->next->data >= n && ptr->data < n
or
ptr->next->data > n && ptr->data <= n

Related

Circular linked list crashes when displayed

I'm trying to make a circular linked list. When I try to display the list after creating it, the program keeps on crashing. Here is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node * next;
} node;
node * createList(int);
void display(node * head);
int main() {
struct node * head;
head = createList(5);
display(head);
}
node * createList(int n) {
int i = 0,data = 0;
struct node * head = NULL;
struct node * temp = NULL;
struct node * p = NULL;
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
temp->next = head;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
return head;
}
void display(node * head) {
struct node * temp = head->next;
while (temp != head) {
printf("%d-> \t",temp->data);
temp = temp->next;
}
printf("\n");
}
What am I doing wrong?
You have set every temp's next to head in temp->next = head; but did it too early (the first is just NULL). Then you tested p->next against NULL in while (p->next != NULL) { but you should have tested against head. Alternatively, you can continue to test against NULL but then you need to initialize temp->next to NULL and assign head to temp->next only after the for loop.
Your display code started from the second link.
Here is a fixed code using the first option in 1. above:
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != head) {
p = p->next;
}
p->next = temp;
}
temp->next = head;
}
Here is a fixed code using the alternative option in 1. above. You still need to initialize temp->next to NULL since malloc() does not initialize.
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
temp->next = NULL;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
if (temp != NULL) {
temp->next = head;
}
But in reality, there is no need to "walk" from the head on every creation. You can simply keep the previous and link it to the next:
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
if (head == NULL) {
head = p = temp;
} else {
p = p->next = temp;
}
}
if (temp != NULL) {
temp->next = head;
}
Here is a fix for the display():
void display(node * head) {
struct node * temp = head;
if (temp != NULL) {
do {
printf("%d-> \t",temp->data);
temp = temp->next;
} while (temp != head);
}
printf("\n");
}
The problem is on the first node you initialize:
struct node *head = NULL;
...
for (i = 0; i < n; i++) {
...
temp->next = head;
So tmp->next == NULL on the first iteration leaving head->next == NULL. That will not work for a circular list. When you attempt to insert the 2nd node:
p = head;
while (p->next != NULL) {
What was head->next again?? (oh, NULL) Dereferencing a NULL pointer (BOOM Segfault!)
Do your circular list correctly. On insertion of the first node set:
if (head == NULL) {
head = temp;
head->next = temp; /* you must set head->next to temp */
} ...
So on the insertion of the remaining nodes you simply need:
} else {
p = head;
while (p->next != head) { /* iterate to last node */
p = p->next;
}
p->next = temp; /* now set p->next = temp */
}
Now, you handle your display() function the same way, e.g.
void display (node *head)
{
if (!head) { /* validate list not empty */
puts ("(list-empty)");
return;
}
struct node *temp = head;
do { /* same loop problem fixed in display() */
printf ("%d-> \t", temp->data);
temp = temp->next;
} while (temp != head);
putchar ('\n');
}
If you make the changes, then you can test your list with:
int main (void) {
struct node *head, *tmp;
head = createList(5);
display (head);
puts ("\niterate from mid-list");
tmp = head;
tmp = tmp->next;
tmp = tmp->next;
display (tmp);
}
Example Use/Output
$ ./bin/lls_circular_fix
0-> 1-> 2-> 3-> 4->
iterate from mid-list
2-> 3-> 4-> 0-> 1->
Lastly, you are not multiplying the type node by head in struct node * head = NULL; Write it as struct node *head = NULL; (the same for all your function declarations as well) Much more readable.
When you go to delete a note from the list, you must create a special case for both head and tail (the last node). In this sense, the singly-linked list takes a bit more effort than a doubly-linked list due to not having a prev node pointer to track the prior node.
Look things over and let me know if you have questions.
A full example would be:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
node *createList (int);
void display (node *head);
int main (void) {
struct node *head, *tmp;
head = createList(5);
display (head);
puts ("\niterate from mid-list");
tmp = head;
tmp = tmp->next;
tmp = tmp->next;
display (tmp);
}
node *createList (int n)
{
int i = 0,data = 0;
struct node *head = NULL;
struct node *temp = NULL;
struct node *p = NULL;
for (i = 0; i < n; i++) {
if (!(temp = malloc (sizeof *temp))) {
perror ("malloc-temp");
return NULL;
}
temp->data = data++;
temp->next = head; /* head is NULL on 1st node insertion */
if (head == NULL) {
head = temp;
head->next = temp; /* you must set head->next to temp */
} else {
p = head;
while (p->next != head) { /* iterate to last node */
p = p->next;
}
p->next = temp; /* now set p->next = temp */
}
}
return head;
}
void display (node *head)
{
if (!head) { /* validate list not empty */
puts ("(list-empty)");
return;
}
struct node *temp = head;
do { /* same loop problem fixed in display() */
printf ("%d-> \t", temp->data);
temp = temp->next;
} while (temp != head);
putchar ('\n');
}

Unable to remove lowest value from linked-list

I created a linked-list in C. I'm trying to create a function that looks at the lowest value in the linked list (which is the head) and the removes the "right-most" instance of that value in the list.
Suppose the linked-list looks like this:
2 -> 2 -> 2 -> 4 -> 5 -> 6
The head in this list is 2. But it's not the head I want to remove. I want to remove the 2 that comes before the 4 (it is the right-most instance of the head).
Here's the function I created to implement this:
double removeLowestValue() {
struct node *temp;
struct node *ptr = head;
double val = ptr->value;
if(head == tail)
{
free(head);
head = NULL;
tail = NULL;
}
else
{
while(ptr->value == ptr->next->value)
{
temp = ptr;
ptr = ptr->next;
val = ptr->value
}
temp->next = NULL;
temp->next = ptr->next;
free(ptr);
return val;
}
}
Then I tried to test if the function works:
int main() {
insertNode(18.0);
insertNode(13.0);
insertNode(11.0);
insertNode(11.0);
insertNode(22.0);
printf("%d", removeLowestValue());
return 0;
}
Unfortunately, the program doesn't print out "11" as expected. Matter of fact, it doesn't print anything at all. What's going on here?
EDIT:
Here's how I implemented the insertNode function:
void insertNode(double value) {
struct node *new_node = create_new_node(value);
struct node *temp = head;
struct node *prev;
if (head == NULL) {
head = new_node;
tail = new_node;
} else {
while (value > temp->value && temp->next != NULL) {
prev = temp;
temp = temp->next;
}
if(value < temp->value || value == temp->value)
{
/*If the value of the new node equals to the value of temp
OR if the value of the new node is less than the value of temp,
then insert the new node right before temp*/
new_node->next = temp;
prev->next = new_node;
}
else if(value > temp->value)
{
temp->next = new_node;
tail = new_node;
}
}
}
your function corrected, of course that supposes the list is sorted :
double removeLowestValue() {
if (head == NULL)
return 0; /* ???? */
else {
node * ptr = head;
node * previous = 0; /* the cell before the cell to remove */
while ((ptr->next != NULL) && (ptr->value == ptr->next->value)) {
previous = ptr;
ptr = ptr->next;
}
/* ptr is now the cell to remove */
double val = ptr->value;
if (ptr == head) {
/* remove the first cell */
ptr = head->next;
free(head);
head = ptr;
if (head == NULL)
/* the list is empty */
tail = NULL;
}
else if (ptr->next == NULL) {
/* all the values are the same in the list
ptr is the last cell */
free(ptr);
/* previous is now the last cell */
previous->next = NULL;
tail = previous;
}
else {
/* ptr is not the first nor the last cell */
previous->next = ptr->next;
free(ptr);
}
return val;
}
}
Concerning insertNode :
it is better to move the declaration of the variables temp and prev where they are useful, they are useless if head null so at the top of the definition
(value < temp->value || value == temp->value) can be just (value <= temp->value) and the else if (...) after can be just an else
when (value <= temp->value) prev can be still unset but used for prev->next = new_node, that appends when you insert 13 after 18 in your main. When (temp == head) you have to update head setting it with new_node
So the corrected version can be :
void insertNode(double value) {
struct node *new_node = create_new_node(value);
if (head == NULL) {
head = new_node;
tail = new_node;
} else {
struct node *temp = head;
struct node *prev = 0; /* = 0 to be sure to have a crash if something wrong */
while ((value > temp->value) && (temp->next != NULL)) {
prev = temp;
temp = temp->next;
}
if (value <= temp->value)
{
/* insert the new node right before temp*/
new_node->next = temp;
if (temp == head)
head = new_node;
else
/* prev was set */
prev->next = new_node;
} else {
/* insert the new node at end */
temp->next = new_node;
tail = new_node;
}
}
}
Using the additional definitions
typedef struct node {
double value;
struct node * next;
} node;
node * create_new_node(double value)
{
node * r = (node *) malloc(sizeof(node));
r->value = value;
r->next = 0;
return r;
}
int main() {
insertNode(18.0);
insertNode(13.0);
insertNode(11.0);
insertNode(11.0);
insertNode(22.0);
printf("%g\n", removeLowestValue());
printf("%g\n", removeLowestValue());
printf("%g\n", removeLowestValue());
printf("%g\n", removeLowestValue());
printf("%g\n", removeLowestValue());
printf("%g\n", removeLowestValue());
return 0;
}
the execution writes (the last 0 indicate the list is empty)
11
11
13
18
22
0

segmentation fault in singly linked list

I am currently writing a program that implements a linked list to maintain a list on integers in sorted order. The program reads the integers from a file in the format of
d [\t] 7
i [\t] 8
i [\t] 7
i [\t] 10
with 'd' meaning delete from the list and 'i' inserting into the list, with no repeat integers allowed. This is the code I have so far:
#include <stdio.h>
#include <stdlib.h>
struct Node{
int data;
struct Node* next;
};
int delete(struct Node** head, int key){
if(head == NULL)
{
return -1;
}
struct Node* ptr = *head;
struct Node* prev = NULL;
while(ptr->data != key && ptr->next!=NULL)
{
prev = ptr;
ptr = ptr->next;
}
if(ptr->data == key)
{
if(prev)
{
prev->next = ptr->next;
}
else
{
*head = ptr->next;
}
free(ptr);
return key;
}
return -1;
}
int insert(struct Node** head, struct Node* newNode){
struct Node* ptr;
if(*head == NULL || (*head)->data >= newNode->data)
{
newNode->next = *head;
*head = newNode;
}
else
{
ptr = *head;
while(ptr->next != NULL && ptr->next->data < newNode->data)
{
ptr = ptr->next;
}
newNode->next = ptr->next;
ptr->next = newNode;
}
return 0;
}
int main(int argc, char* argv[]){
FILE *fp = fopen(argv[1], "r");
int num, found;
char c;
struct Node* head = NULL;
struct Node* ptr = head;
while(fscanf(fp, "%c\t%d\n", &c, &num)!=EOF)
{
for(ptr=head; ptr!=NULL; ptr=ptr->next)
{
if(ptr->data == num)
{
found = 1;
}
}
if(found != 1)
{
if(c == 'i')
{
struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = num;
newNode->next = NULL;
insert(&head, newNode);
}
}
if(c == 'd')
delete(&head, num);
}
found = 0;
}
for(ptr=head; ptr!=NULL; ptr=ptr->next)
{
printf("%d ", ptr->data);
}
return 0;
}
It works fine when the first letter is 'i', but whenever the first letter is 'd' I get a segmentation fault. Why is this?
When you try to delete a node first thing you do, the list is empty and inside the delete function *head (notice the dereference!) is a null pointer.
Since *head is a null pointer, so will ptr be, and you then dereference ptr without checking for that.
You might want to modify the initial check to be head == NULL || *head == NULL.
whenever the first letter is 'd' I get a segmentation fault.
If the first letter is D, your list is still empty when you call delete.
In your first if, you need to dereference your pointer, as #SomeProgrammerDude mentionned.

C double linked list insertion sort memory fault

I wanted to implement insertion sort on dl_list containing char* values but I got a segmentation fault after running program (no warnings, I use gcc).
This is my structure:
struct node;
typedef struct node {
char *name;
char *surname;
char *birth_date;
char *email;
char *phone;
char *address;
struct node *next;
struct node *prev;
} node;
//doubly linked_list
typedef struct dl_list {
node *head;
node *tail;
} dl_list;
I sort it by surname, later name. When values are same it return 0, if alpha should be before beta it return -1, otherwise 1:
int compare(node *alpha, node *beta) {
int a_surn_len = strlen(alpha->surname);
int b_surn_len = strlen(beta->surname);
for (int i = 0; i < ((a_surn_len > b_surn_len) ? b_surn_len : a_surn_len); i += 1) {
if (alpha->surname[i] > beta->surname[i]) return 1;
if (alpha->surname[i] < beta->surname[i]) return -1;
//if (alpha->surname[i] == beta->surname[i]) continue;
}
if (a_surn_len != b_surn_len) return a_surn_len > b_surn_len ? 1 : -1;
int a_n_len = strlen(alpha->name);
int b_n_len = strlen(beta->name);
for (int j = 0; j < ((a_n_len > b_n_len) ? b_n_len : a_n_len); j += 1) {
if (alpha->name[j] > beta->name[j]) return 1;
if (alpha->name[j] < beta->name[j]) return -1;
//if (alpha->surname[i] == beta->surname[i]) continue;
}
if (a_n_len != b_n_len) return a_n_len > b_n_len ? 1 : -1;
return 0;
}
And here insertion algorithm on my list:
dl_list *list_sort(dl_list *list) {
// zero or one element in list
if (list->head == NULL || list->tail == NULL)
return list;
// new_head is the first element of resulting sorted list
node *new_head = NULL;
while (list->head != NULL) {
node *current = list->head;
list->head = list->head->next;
// insert the first element into an empty sorted list
if (new_head == NULL) {
current->next = new_head;
new_head = current;
new_head->prev = NULL;
// or as the head of the sorted list
} else
if (compare(current, new_head) == -1) {
current->next = new_head;
new_head->prev = current;
new_head = current;
new_head->prev = NULL;
} else {
// insert current element into proper position in non-empty sorted list
node *ptr = new_head;
while (ptr != NULL) {
// middle of the list
if (compare(current, ptr->next) == -1) {
current->next = ptr->next;
ptr->next->prev = current;
ptr->next = current;
current->prev = ptr;
break; //done
// last element of the sorted list
} else
if (ptr->next == NULL) {
current->next = ptr->next;
ptr->next = current;
current->prev = ptr;
break;//done
}
ptr = ptr->next;
}
}
}
list->head = new_head;
node *ptr2;
for (ptr2 = list->head; ptr2->next != NULL; ptr2 = ptr2->next);
list->tail = ptr2;
return list;
}
I tried to check this code on paper and it seems to work fine, on some 4-5 elements lists.
The problem is in the insertion loop: you must check if ptr->next is not NULL before comparing current with node ptr->next:
// insert current element into proper position in non-empty sorted list
node *ptr = new_head;
while (ptr != NULL) {
if (ptr->next == NULL) {
current->next = ptr->next;
ptr->next = current;
current->prev = ptr;
break;
} else
if (compare(current, ptr->next) < 0) {
current->next = ptr->next;
ptr->next->prev = current;
ptr->next = current;
current->prev = ptr;
break;
}
ptr = ptr->next;
}
You could also simplify the comparison function with strcmp():
int compare(const node *alpha, const node *beta) {
int res;
if ((res = strcmp(alpha->surname, beta->surname)) != 0)
return res;
if ((res = strcmp(alpha->name, beta->name)) != 0)
return res;
return 0;
}
And you should just compare the return value with 0 instead of explicitly with -1 or 1.
Here is a simplified version:
dl_list *list_sort(dl_list *list) {
// zero or one element in list
if (list->head == NULL || list->tail == NULL)
return list;
// new_head is the first element of resulting sorted list
node *new_head = NULL;
while (list->head != NULL) {
node *current = list->head;
list->head = list->head->next;
if (new_head == NULL) {
// insert the first element into an empty sorted list
current->prev = current->next = NULL;
new_head = current;
} else
if (compare(current, new_head) < 0) {
// or as the head of the sorted list
current->next = new_head;
current->prev = NULL;
new_head->prev = current;
new_head = current;
} else {
// insert current element into proper position in non-empty sorted list
node *ptr = new_head;
while (ptr != NULL) {
if (ptr->next == NULL) {
current->next = NULL;
ptr->next = current;
current->prev = ptr;
break;
} else
if (compare(current, ptr->next) < 0) {
current->next = ptr->next;
ptr->next->prev = current;
ptr->next = current;
current->prev = ptr;
break;
}
ptr = ptr->next;
}
}
}
list->head = new_head;
node *ptr2;
for (ptr2 = list->head; ptr2->next != NULL; ptr2 = ptr2->next)
continue;
list->tail = ptr2;
return list;
}
Your code is quite long and it will be hard to debug without a minimal example. Maybe , you can compile with the -g flag and use valgrind. That tool will give you the line of the memory fault :)
Just use: valgrind --track-origins=yes ./executable
Your problem is that your insertion loop doesn't really make sense:
node *new_head=NULL;
while(list->head != NULL){
node *current=list->head;
list->head=list->head->next;
// insert the first element into an empty sorted list
if(new_head == NULL){
current->next=new_head;
new_head=current;
new_head->prev=NULL;
1) You set new_head to be a pointer to NULL
2) You take keep a reference of head in current and make head=head->next
3) On your first loop new_head is still NULL, so you enter the if statement and set current->next=new_head. But new_head points to NULL, so this causes problems!
4) Now when you set new_head=current, current/new_head's next pointer points to NULL.
5) Finally you set new_head->prev to NULL, meaning that now current/new_head point to NULL in both directions, but your loop is waiting for list->head to be NULL! This never happens, so once you've done an iteration and try to move forward you end up in your else block
} else{
// insert current element into proper position in non-empty sorted list
node *ptr=new_head;
while(ptr != NULL){
// middle of the list
if(compare(current, ptr->next) == -1){
current->next=ptr->next;
ptr->next->prev=current;
ptr->next=current;
current->prev=ptr;
break; //done
// last element of the sorted list
} else if(ptr->next == NULL ){
current->next=ptr->next;
ptr->next=current;
current->prev=ptr;
break;//done
}
ptr=ptr->next;
}
}
6) This block tries to compare current to new_head->next. But new_head->next is NULL!

Inserting in Binary Search Tree (C) using for loop

I'm having trouble inserting in a Binary Search Tree using for loop, when I call the InorderTraversal function, there is no output all I get is a blank line, as far as I think rest of the code is okay the only problem is in the insert function.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct BinaryTree{
int data;
struct BinaryTree *left;
struct BinaryTree *right;
} node;
node* Insert(node* head, int value)
{
_Bool flag = true;
for(node *temp = head; flag == true; (temp = (value >= temp->data)?(temp->right):(temp->left)))
{
if(temp == NULL)
{
temp = (node*)malloc(sizeof(node*));
temp->data = value;
temp->left = NULL;
temp->right = NULL;
flag = false;
}
}
return head;
}
void InorderTraversal(node* head)
{
if(head == NULL)
{
return;
}
InorderTraversal(head->left);
printf("%d ",head->data);
InorderTraversal(head->right);
}
int main(void)
{
node *head = NULL;
for(int i = 0; i < 40; i++)
{
head = Insert(head,i);
}
InorderTraversal(head);
return 0;
}
Here try these changes in your Insert function
node* Insert(node *head, int value)
{
if(!head) //Explicitly insert into head if it is NULL
{
head = malloc(sizeof *head);
head->data = value;
head->left = NULL;
head->right = NULL;
return head;
}
for(node *temp = head,*temp2 = head; ;(temp = (value >= temp->data)?(temp->right):(temp->left)))
{
if(temp == NULL)
{
temp = malloc(sizeof *temp);
temp->data = value;
temp->left = NULL;
temp->right = NULL;
if(value >= temp2->data) //update previous nodes left or right pointer accordingly
temp2->right = temp;
else
temp2->left = temp;
break;
}
temp2 = temp; //Use a another pointer to store previous value of node
}
return head;
}
Call me crazy, but shouldn't that malloc(sizeof(node*)) be malloc(sizeof node)?
I am not that so informed, other than being able to read C, so excuse me if this is simply wrong...
Edit: ... or malloc(sizeof * temp)
When you insert the first node you dereference an uninitialized pointer here:
temp->data
Where temp is head and head in uninitialized and pointing to NULL.
So you first have to make special case when head is NULL:
if( !head )
{
head = malloc(sizeof(node));
head->data = value;
head->left = NULL;
head->right = NULL;
return head ;
}
When you continue adding elements you don't update the pointer of the last node. Your for loop should have an extra pointer to the previous node and when you get to the last node and find NULL update the previous nodes left or right pointer.
if(temp == NULL) //wrong, should be: not equal
{
temp = (node*)malloc(sizeof(node*)); //wrong, should be: sizeof the node not the pointer
temp->data = value;
temp->left = NULL;
temp->right = NULL;
flag = false; //use break instead
}
here the previous node pointer left or right is not updated and when you search you can't find any node.

Resources