I'm trying to clear a list. I keep getting an error that says free() called on an unallocated pointer current. I'm not sure what the problem is I have seen multiple sites use this code.
This is the whole program upon request:
I am only suppose to fill in these three functions.
#include "orderedList.h"
Node *orderedInsert(Node *p, int newval)
/* Allocates a new Node with data value newval
and inserts into the ordered list with
first node pointer p in such a way that the
data values in the modified list are in
nondecreasing order as the list is traversed.
*/
{
Node * q = NULL;
q = (Node*)malloc(sizeof(Node));
q->data = newval;
q->next = NULL;
if (q == NULL)
{
return q;
}
if (p == NULL || newval <= p->data )
{
q->next = p->next;
return q;
}
Node *tmp, *last;
tmp = (Node*)malloc(sizeof(Node));
tmp = p;
while (tmp->next != NULL && tmp->data <= newval)
{
last = tmp;
tmp = tmp->next;
}
q->next = tmp;
last->next = q;
return p;
}
void printList(FILE *outfile, Node *p)
/* Prints the data values in the list with
first node pointer p from first to last,
with a space between successive values.
Prints a newline at the end of the list.
*/
{
Node* temp = p;
while(temp != NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
void clearList(Node **p)
/* Deletes all the nodes in the list with
first node pointer *p, resulting in *p
having value NULL. Note that we are passing
a pointer by address so we can modify that
pointer.
*/
{
Node* current = *p;
Node* temp;
while(current != NULL)
{
temp = current->next;
free(current);
current = temp;
}
*p = NULL;
}
sample code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct node {
int data;
struct node *next;
} Node;
Node *orderedInsert(Node *p, int newval){
Node *q;
if(NULL==(q = (Node*)malloc(sizeof(Node)))){
perror("malloc");
exit(EXIT_FAILURE);
}
q->data = newval;
q->next = NULL;
if (p == NULL || newval <= p->data ){
q->next = p;
return q;
}
Node *tmp = p, *last;
while (tmp != NULL && tmp->data < newval) {
last = tmp;
tmp = tmp->next;
}
q->next = tmp;
last->next = q;
return p;
}
void printList(FILE *outfile, Node *p){
Node* temp = p;
while(temp != NULL){
fprintf(outfile, "%d ", temp->data);
temp = temp->next;
}
fprintf(outfile, "\n");
}
void clearList(Node **p){
Node* current = *p;
while(current != NULL){
Node *temp = current->next;
free(current);
current = temp;
}
*p = NULL;
}
int main (void){
Node *head = NULL;
int i, v;
printf("The generated number\n");
for(i=0; i<10; ++i){
v = rand()%10;
printf("%d ", v);
head = orderedInsert(head, v);
}
printf("\n");
printf("The orderd number\n");
printList(stdout, head);
clearList(&head);
return 0;
}
The code is fundamentally ok, supposing that you don't need to free anything other than the Node objects themselves. The problem is likely with your list. In particular, if it contains a loop then you will see the behavior you describe, because your function will eventually come back to a Node it has already freed.
please read my added comments regarding the OPs code
#include "orderedList.h"
Node *orderedInsert(Node *p, int newval)
/* Allocates a new Node with data value newval
and inserts into the ordered list with
first node pointer p in such a way that the
data values in the modified list are in
nondecreasing order as the list is traversed.
*/
{
Node * q = NULL;
q = (Node*)malloc(sizeof(Node));
q->data = newval; // if q is NULL, then setting an offset from address 0
// which is a real good way to cause a seg fault event
q->next = NULL; // if q is NULL, then setting an offset from address 0
// which is a real good way to cause a seg fault event
if (q == NULL)
{
return q; // odd, returning a null,
// I would expect to return p
}
if (p == NULL || newval <= p->data )
{
q->next = p->next; // odd, if p was null (I.E. adding first entry into list)
// then p->next is some offset from address 0
// a real good way to cause a seg fault event
// if not first entry in list and new data < first entry in list data
// then set q->next to be inserted before the current/existing list
// however,
// (assuming p is the head of the list and not a ptr to the first entry)
// then p->next needs to be set to q
return q;
}
Node *tmp, *last;
tmp = (Node*)malloc(sizeof(Node)); // failed to check if malloc was successful
tmp = p; // overlays the pointer to the 'just' malloc'd memory
// and a good way to cause a seg fault event if malloc failed
-- I stopped checking the code here --
while (tmp->next != NULL && tmp->data <= newval)
{
last = tmp;
tmp = tmp->next;
}
q->next = tmp;
last->next = q;
return p;
}
void printList(FILE *outfile, Node *p)
/* Prints the data values in the list with
first node pointer p from first to last,
with a space between successive values.
Prints a newline at the end of the list.
*/
{
Node* temp = p;
while(temp != NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
void clearList(Node **p)
/* Deletes all the nodes in the list with
first node pointer *p, resulting in *p
having value NULL. Note that we are passing
a pointer by address so we can modify that
pointer.
*/
{
Node* current = *p;
Node* temp;
while(current != NULL)
{
temp = current->next;
free(current);
current = temp;
}
*p = NULL;
}
Related
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');
}
I am currently working on a program based on linked-list. But my delete function causes crashes on my program. I want to allow users to delete a flight by it's fligt number. But I don't know what causes crash. How to fix this? Thanks
struct flight {
int number;
char source[20];
char destination[20];
struct flight* next;
};
void enter();
void display();
void delete();
int count();
typedef struct flight NODE;
NODE* head_node, * first_node, * temp_node = 0, * prev_node, next_node;
int data;
char data2[20], data3[20];
void delete()
{
temp_node = (NODE*)malloc(sizeof(NODE));
temp_node = first_node;
int counter, flightno, j;
temp_node->number = data;
counter = count();
printf("\nEnter flight number to delete: \n");
scanf("%d", &flightno);
for (j = 0; j <= counter; j++)
{
if (flightno == data) {
temp_node = temp_node->next;
first_node = temp_node;
printf("\nFlight log deleted.\n");
}
else
{
printf("Flight number not found.");
}
}
}
int count()
{
int count = 0;
temp_node = first_node;
while (temp_node != 0) {
count++;
temp_node = temp_node->next;
}
return count;
}
Short answer: Avoid global variables!
In your delete function you set the value of the global variable temp_node.
Then you call the function count. In count you also use the global variable temp_node. You change it until it has the value NULL.
Then back in the delete function, you do:
temp_node = temp_node->next;
Dereference of a NULL pointer! That is real bad and crashes your program.
So to start with: Get rid of all global variables
As an example, your count function should be:
int count(NODE* p)
{
int count = 0;
while (p != NULL) {
count++;
p = p->next;
}
return count;
}
and call it like: counter = count(first_node);
And your delete function could look like:
NODE* delete(NODE* first_node) { ... }
That said ...
The principle in your delete function is wrong. You don't need to count the number of nodes. Simply iterate until you reach the end, i.e. next is NULL.
Further - why do you malloc memory in the delete function? And why do you overwrite the pointer just after malloc? Then you have a memory leak.
temp_node = (NODE*)malloc(sizeof(NODE)); // WHY??
temp_node = first_node; // UPS... temp_node assigned new value.
// So malloc'ed memory is lost.
Now - what happens when you find the matching node:
if (flightno == data) {
temp_node = temp_node->next;
first_node = temp_node; // UPS.. first_node changed
printf("\nFlight log deleted.\n");
}
Then you change first_node. So all nodes before the current node is lost! That's not what you want. You only want to change first_node when the match is on the very first node in the linked list.
Then: for (j = 0; j <= counter; j++) --> for (j = 0; j < counter; j++) But as I said before... don't use this kind of loop.
Use something like:
while (temp_node != NULL)
{
...
temp_node = temp_node->next;
}
BTW: Why do you do a print out in every loop? Move the negative print out outside the loop.
A delete function can be implemented in many ways. The below example is not the most compact implementation but it's pretty simple to understand.
NODE* delete(NODE* head, int value_to_match)
{
NODE* p = head;
if (p == NULL) return NULL;
// Check first node
if (p->data == value_to_match)
{
// Delete first node
head = head->next; // Update head to point to next node
free(p); // Free (aka delete) the node
return head; // Return the new head
}
NODE* prev = p; // prev is a pointer to the node before
p = p->next; // the node that p points to
// Check remaining nodes
while(p != NULL)
{
if (p->data == value_to_match)
{
prev->next = p->next; // Take the node that p points to out
// of the list, i.e. make the node before
// point to the node after
free(p); // Free (aka delete) the node
return head; // Return head (unchanged)
}
prev = p; // Move prev and p forward
p = p->next; // in the list
};
return head; // Return head (unchanged)
}
and call it like:
head = delete(head, SOME_VALUE);
You are probably making an extra loop in your delete function. You should check if you are deleting an node which isn't part of your linked list.
void
LInsert (LIST * l, int x, int pos)
{
struct Node *new, *p; // p: previous node
// create a new node
new = (struct Node *) malloc (sizeof (struct Node));
new->val = x;
if (pos == 0)
{ // insert to start
new->next = l->head;
l->head = new;
}
else
{
// insert after p
p = l->head;
while (p != NULL && pos > 1)
{
p = p->next;
--pos;
}
if (p == NULL)
{
printf ("LInsert: Position not possible\n");
return;
}
new->next = p->next;
p->next = new;
}
l->size++;
}
This is a function of inserting a node to a linked list. I don't understand a few lines in this program.
In the first if condition there is a line new->next=l->head; From my thinking it means that in the "next" part of the new node it will store the what's in the head node(an address probably), but why?. It makes the linked list a circular linked list but this is just a simple linked list.
Also near the end new->next=p->next what does this mean.It makes the linked list circular again.
Hope the indentation is correct I always get people yelling at me for wrong indentation
Here is the complete code which includes struc declaration and stuff
#include <stdio.h>
#include <stdlib.h>
struct Node {
int val;
struct Node *next;
};
struct List {
struct Node *head;
int size;
};
// LIST is new name for "struct List"
typedef struct List LIST;
void LInit(LIST *l){ // Initialize list to empty
l->head = NULL; // pointer to first node
l->size = 0; // number of nodes
}
int LGetPos(LIST *l, int x) {
struct Node *p;
int i=0;
// go through all nodes
for (p=l->head; p!=NULL; p=p->next)
if (p->val == x) return i; // found
else i++; // next
return -1; // not found in the list
}
int LGetAt(LIST *l, int pos) {
struct Node *p=l->head;
int i;
// go to position
for(i=0; p!=NULL && i<pos; i++) p = p->next;
if(p) return p->val; // if exists, return it
else { printf("LDelete: Position not exist\n"); return -99; }
}
void LInsert(LIST *l, int x, int pos) {
struct Node *new, *p; // p: previous node
// create a new node
new = (struct Node *) malloc(sizeof(struct Node));
new->val = x;
if(pos==0) { // insert to start
new->next = l->head;
l->head = new;
}
else { // insert after p
p = l->head;
while(p!=NULL && pos>1) { p = p->next; --pos; }
if(p==NULL) { printf("LInsert: Position not possible\n"); return; }
new->next = p->next;
p->next = new;
}
l->size++;
}
void LDelete(LIST *l, int pos) {
struct Node *p, *d; // p: previous
if(l->head == NULL) return;
if(pos==0) { // delete first node
d = l->head;
l->head = d->next;
}
else { // delete after p
p = l->head;
while(pos>1 && p) { p = p->next; --pos; }
if(p==NULL) { printf("LDelete: Position not exist\n"); return; }
d = p->next;
p->next = p->next->next;
}
l->size--;
free(d);
}
int LIsEmpty(LIST * l){
return (l->size == 0);
}
int LSize(LIST * l){
return (l->size);
}
void LDisplay(LIST *l) {
struct Node *p;
printf("List: ");
for(p=l->head; p!=NULL; p=p->next)
printf("--> %d ", p->val);
printf("\n");
}
int LHeadOf(LIST *l) {
if (!LIsEmpty(l)) return l->head->val;
else {
printf("LHeadOf: Linked list empty\n");
return -99;
}
}
int main() {
LIST list;
LInit(&list);
LDisplay(&list);
LInsert(&list, 3, 0);
LInsert(&list, 4, 0);
LInsert(&list, 5, 2);
LDisplay(&list);
printf("Value at 1: %d\n", LGetAt(&list, 1));
printf("Location of 4: %d\n", LGetPos(&list, 4));
LDelete(&list, 1);
LDisplay(&list);
return 0;
}
I don't understand a few lines in this program
Okay - let's take a look of those lines...
here is a line new->next=l->head; From my thinking it means that in the "next" part of the new node it will store the what's in the head node(an address probably), but why?
That line is used to insert the new element in front of the current head element. So
new->next=l->head; // Make the new element point to current head
l->head = new; // Change head to point to the new element as it is now the front element
Also near the end new->next=p->next what does this mean.It makes the linked list circular again.
Well, it doesn't make the list circular. It simply insert the new element somewhere in the middle of the list.
new->next = p->next; // Make new point to the element after p
p->next = new; // Make p point to new
// In this way new has between inserted after p and
// before the element that folloed p
I am working on a problem for a class and we're learning linked lists in C. I was given a section of code to complete, specifically the delete a node section and I'm having a problem deleting head. Every time I try to delete head I receive a segmentation fault. Can someone tell me what I'm doing wrong?
EDIT2
My teacher wrote everything but the lookup and delete functions.
I have fixed the glaring errors pointed out by the gentleman from Moscow and Mr. Petriuc, however the code still doesn't run. It does compile, but there is still a problem in head.
Here is the full code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "linkedList.h"
// keep an unsorted array of char *'s, strings.
/*
Create an empty node, return 0 if fail, 1 if succeed
*/
struct node * createNode() {
struct node *p = (struct node *) malloc(sizeof(struct node));
if (p == NULL) return 0;
p->prev = p->next = NULL;
p->data = NULL;
}
/*
Lookup string in the list, return pointer to node of first occurence, NULL if not found.
*/
struct node * lookup(struct node *head, char *s) {
struct node *p;
for(p=head; p!=NULL; p=p->next){
if(strcmp(s,p->data)==0){
return p;
}
// just like print, but check if strcmp(s, p->data) == 0, and if so then return p
}
return NULL;
}
/*
Insert new string into the linked list, return 1 if success, 0 if fail.
*/
int insert(struct node **head, char *newS, int insertDuplicate) {
struct node *p = lookup(*head, newS);
if (p == NULL || insertDuplicate) {
// create a new node, put it at the front.
p = createNode();
if (p == NULL) return 0;
// put the string in the new node
p->data = (char *) malloc(sizeof(char) * (1 + strlen(newS)));
if (p->data == NULL) return 0;
strcpy(p->data, newS);
// note: make changes and use old head before setting the new head...
p->next = *head; // next of new head is previous head
if (*head != NULL)
(*head)->prev = p; // previous of old head is new head
*head = p; // set the new head
}
return 1;
}
/*
Remove string from list if found, return 1 if found and deleted, 0 o/w.
*/
int delete(struct node **head, char *s) {
struct node *p,*pr,*ne;
// first do a lookup for string s, call lookup.
p=lookup(*head, s);
if(p==*head){
*head = p->next;
free(p);
return 1;
}
if(p!=NULL){
printf("%s",p);
pr = p->prev;
ne = p->next;
free(p->data);
free(p);
if(pr==NULL||ne==NULL){
return 0;
}
pr->next=ne;
ne->prev=pr;
// if lookup returns NULL, done, return 0.
// if lookup returns p, not NULL,
// pr = p->prev, ne = p->next
// set pr->next to ne, ne->prev to pr
// but what if pr or ne is NULL
// and note that we need node **head because if delete head,
// need to update head pointer back in calling function, in
// here if you want head probably do *head. like in insert.
// also, before the pointer to the one you're deleting is gone,
// free p->data and p.
return 1;
}
return 0;
}
void print(struct node *head) {
struct node *p;
for(p = head; p != NULL ; p = p->next) {
printf("%s\n", p->data);
}
}
You are doing
p->next = *head;
But p is not assigned anywhere.
Your function does not make sense. You call the function lookup three times.
Moreover you use pointers that were not initialized like for example
p->next = *head;
or
printf("%s",p);
pr = p->prev;
ne = p->next;
The function can be written the following way
int delete( struct node **head, char *s )
{
int success;
struct node *target = lookup( *head, s );
if ( ( success = target != NULL ) )
{
if ( target->prev != NULL )
{
target->prev->next = target->next;
}
else
{
*head = target->next;
}
if ( target->next != NULL )
{
target->next->prev = target->prev );
}
free( target );
}
return success;
}
Take into account that the second parameter of the function and the corresponding parameter of the function lookup should be declared with qualifier const
int delete( struct node **head, const char *s ) ;
^^^^^
struct node * lookup( struct node *head, const char *s );
^^^^^^
Simplified delete() function. I inlined lookup() because the function as it is is worthless (you need a pointer to pointer, not a pointer to act upon)
/*
Remove string from list if found, return 1 if found and deleted, 0 o/w.
*/
int delete(struct node **head, char *s) {
struct node *tmp;
// first do a lookup for string s, no need to call call lookup.
for( ;*head; head = &(*head)->next ){
if (!strcmp( (*head)->data, s)) break;
}
if (!*head) return 0; // not found
tmp = *head
*head = tmp->next
free(tmp);
return 1;
}
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