pointer to a struct becomes NULL at every function call - c

The problem is that every time the function addNodePos is being called head pointer is NULL (saw that in debugger), and it just creates a list of one node, which points to itself as it is a circular doubly-linked list. And it displays "List is empty." because list is also NULL, when passing to a printList function. Have been trying to understand why but still there is no result.
Here is the code (removed excessive code according to SSCCE)
#include <stdio.h>
#include <stdlib.h>
struct DoubleList
{
int id;
struct DoubleList *next;
struct DoubleList *prev;
};
void addNodePos(struct DoubleList* head, int value, int position);
void printList (struct DoubleList* head);
//void clearList (struct DoubleList* head);
int main()
{
int value, position;
struct DoubleList *list = NULL;
printf("\nvalue: ");
scanf("%x", &value);
printf("position: ");
scanf("%d", &position);
addNodePos(list, value, position);
printf("\nvalue: ");
scanf("%x", &value);
printf("position: ");
scanf("%d", &position);
addNodePos(list, value, position);
printList(list);
//clearList(list);
return 0;
}
void addNodePos(struct DoubleList* head, int value, int position)
{
int i;
struct DoubleList *node;
if ( (node = malloc (sizeof(struct DoubleList))) != NULL ){
node->id=value;
if (head==NULL) {
// points to itself as it is the only node in a list
node->next=node;
node->prev=node;
head=node;
} else {
struct DoubleList *current=head;
for (i = position; i > 1; i--)
current=current->next;
// reassign pointers -- relink nodes
current->prev->next=node;
node->prev=current->prev;
node->next=current;
current->prev=node;
}
}
printf("Element has been added.\n\n");
}
void printList(struct DoubleList* head)
{
if (head==NULL)
printf("\nList is empty.\n\n");
else {
struct DoubleList *current=head;
printf("\nThe list: ");
do {
printf("%d", current->id);
current=current->next;
if(current != head)
printf("<->");
} while(current!=head);
printf("\n\n");
}
}

The address of head is passed by value, so your changes are only reflected in the function itself. You have to pass a pointer to the address of head so that you can change the value.
int main() {
...
addNodePos(&list, value, position);
...
}
void addNodePos(struct DoubleList** headPtr, int value, int position)
{
struct DoubleList *head = *headPtr;
int i;
struct DoubleList *node;
if ( (node = malloc (sizeof(struct DoubleList))) != NULL ){
node->id=value;
if (head==NULL) {
// points to itself as it is the only node in a list
node->next=node;
node->prev=node;
head=node;
} else {
struct DoubleList *current=head;
for (i = position; i > 1; i--)
current=current->next;
// reassign pointers -- relink nodes
current->prev->next=node;
node->prev=current->prev;
node->next=current;
current->prev=node;
}
}
printf("Element has been added.\n\n");
}

With a great help of users (which shared some very useful links), I have managed solving it.
Solution: to modify caller memory, pass a pointer to that memory.
After a bit updating, I leave here correctly working code:
#include <stdio.h>
#include <stdlib.h>
struct DoubleList
{
int id;
struct DoubleList *next;
struct DoubleList *prev;
};
void addNodePos(struct DoubleList** headRef, int value, int position);
void printList (struct DoubleList** headRef);
//void clearList (struct DoubleList** headRef);
int main()
{
int value, position;
struct DoubleList *list = NULL;
printf("\nvalue: ");
scanf("%x", &value);
printf("position: ");
scanf("%d", &position);
addNodePos(&list, value, position);
printf("\nvalue: ");
scanf("%x", &value);
printf("position: ");
scanf("%d", &position);
addNodePos(&list, value, position);
printList(&list);
//clearList(head);
return 0;
}
void addNodePos(struct DoubleList** headRef, int value, int position)
{
int i;
struct DoubleList *node;
if ( (node = malloc (sizeof(struct DoubleList))) != NULL ){
node->id=value;
if ( (*headRef)==NULL) {
// points to itself
node->next=node;
node->prev=node;
(*headRef)=node;
} else {
struct DoubleList *current=(*headRef);
for (i = position; i > 1; i--)
current=current->next;
// reassign pointers -- relink nodes
current->prev->next=node;
node->prev=current->prev;
node->next=current;
current->prev=node;
}
}
printf("Element has been added.\n\n");
}
void printList(struct DoubleList** headRef)
{
if ( (*headRef)==NULL)
printf("\nList is empty.\n\n");
else {
struct DoubleList *current=(*headRef);
printf("\nThe list: ");
do {
printf("%x", current->id);
current=current->next;
if(current != (*headRef))
printf("<->");
} while(current!=(*headRef));
printf("\n\n");
}
}

Related

How can I print input data?

As a practice for final exam, I am practicing a linked list. But now I am stuck at printing input data on my code. I made this linked list and want to print input data. But my code does not print anything.
What's wrong with my code?
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int a,b ;
struct Node* next;
}NODE;
void makenode()
{
int a;
int b;
printf("enter the name : ");
scanf("%d",&a);
printf("enter the sur name : ");
scanf("%d",&b);
NODE* node1=malloc(sizeof(NODE));
node1->a=a;
node1->b=b;
node1->next=NULL;
return node1;
}
void printList()
{
NODE *ptr=NULL;
while(ptr!=NULL){
printf("%d", ptr->a);
printf("%d", ptr->b);
ptr = ptr->next;
}
}
int main()
{
NODE *head = malloc(sizeof(NODE));
head->next=NULL;
makenode();
printList();
return 0;
}
makenode() return type is void, it should be NODE*.
printList() does not fech the list so it can't know what to print, moreover ptr is NULL so it never enters the print loop.
Fixed code with comments:
Live demo
#include <stdlib.h>
#include <stdio.h>
typedef struct Node {
int a, b;
struct Node *next;
} NODE;
NODE* makenode() { //return type NODE*
NODE *node1 = malloc(sizeof(*node1));
printf("enter the name : ");
scanf("%d", &node1->a);
printf("enter the sur name : ");
scanf("%d", &node1->b);
node1->next = NULL;
return node1;
}
void printList(const NODE *ptr) { //pass NODE* ptr as an argument
int i = 1;
while (ptr != NULL) {
printf("Node %d\n", i++);
printf("a: %d\n", ptr->a);
printf("b: %d\n", ptr->b);
ptr = ptr->next;
}
}
int main() {
//make first node
NODE *head = makenode(); //assing node
// add one more node
NODE* node = makenode();
head->next = node; //chain second node
printList(head); //print nodes
return EXIT_SUCCESS;
}
On another note:
It's kind of strange that the names are int and not strings.
You could do:
Live demo
typedef struct Node {
char name[100]; //names as strings
char surname[100];
struct Node *next;
} NODE;
NODE* makenode() { //return type NODE*
NODE *node1 = malloc(sizeof(*node1));
printf("enter the name : ");
scanf(" %99[^\n]", node1->name);
printf("enter the sur name : ");
scanf(" %99[^\n]", node1->surname);
node1->next = NULL;
return node1;
}
void printList(const NODE *ptr) { //pass NODE* ptr as an argument
int i = 1;
while (ptr != NULL) {
printf("Node %d\n", i++);
printf("Name: %s\n", ptr->name);
printf("Surname: %s\n", ptr->surname);
ptr = ptr->next;
}
}
//...
//main is the same

printing the nodes in linked list in c

here is a program which inserting 2 names 2 paths and 2 duration s into linked list (struct of linked lists) , printing them and swapping between them when the duration of the first node is 8.
but when the program printing the nodes its prints from all of the nodes the name and the path of the last node
please help me
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Frame
{
char *name;
unsigned int duration;
char *path; // may change to FILE*
}*n3;
typedef struct Frame frame_t;
struct Link
{
frame_t *frame;
struct Link *next;
}*n ;
typedef struct Link link_t;
struct Link* insert(struct Link *n3);
void print(struct Link* head, int flag);
void swap(struct Link **head, int value);
#define MAX_PATH_SIZE (256)
#define MAX_NAME_SIZE (50)
int main()
{
struct Link* head = NULL;
int flag = 0;
int num = 0;
char namearray[MAX_NAME_SIZE] = { 0 };
char patharray[MAX_PATH_SIZE] = { 0 };
printf("1\n");
printf("\n");
for (int i = 0; i < 2; i++)
{
printf("Enter a number you want to insert - ");
scanf("%d", &num);
printf("\nEnter the name - ");
scanf("%s", &namearray);
printf("\nEnter the path - ");
scanf("%s", &patharray);
printf("\n");
head = insert(head,num,namearray,patharray);
}
print(head, flag);
swap(&head, 8);
printf("1\n");
system("pause");
return 0;
}
struct Link *insert(struct Link *p, int n, char namearray[MAX_NAME_SIZE], char patharray[MAX_PATH_SIZE]) //insert func
{
struct node *temp;
if (p == NULL) //if the node is empty
{
p = (struct Link *)malloc(sizeof(struct Link)); //gives memory to the node
p->frame = (struct Frame *)malloc(sizeof(struct Frame));
if (p == NULL)
{
printf("Error\n");
}
else
{
printf("The number added to the end of the list\n");
}
p->frame->duration = n; //its runing untill the node item is NULL
p->frame->name = namearray;
p->frame->path = patharray;
p->next = NULL;
}
else
{
p->next = insert(p->next, n , namearray , patharray);/* the while loop replaced by
recursive call */
}
return (p);
}
void print(struct Link* head , int flag)//print func
{
if (head == NULL && flag == 0) //if the node is empty
{
printf("The list is empty\n");
return 1;
}
if (head == NULL && flag != 0) //if the node isnt empty but we are in the NULL (last) item of the node
{
printf("\n");
printf("the nodes of the list printed\n");
return;
}
printf("%d ", head->frame->duration);//prints the currect item
printf("\n");
printf("%s ", head->frame->name);//prints the currect item
printf("\n");
printf("%s ", head->frame->path);//prints the currect item
printf("\n");
print(head->next, ++flag);//calls the func recursevly
return 1;
}
void swap(struct Link **head, int value)
{
while (*head && (*head)->frame->duration != value)
{
head = (*head)->next;
}
if (*head && (*head)->next)
{
struct list *next = (*head)->next->next;
(*head)->next->next = *head;
*head = (*head)->next;
(*head)->next->next = next;
}
}
here is the print :
the print of the program

Why does this linked-list ordered insert segfault?

I am working on a program that inserts into a linked-list in sorted order, but it keeps seg faulting, and I can't figure out why. I suspect it has something to do with the pointers, but I can't tell as these are still a little bit confusing to me at this point in my programming career. Also, I must keep the insert prototype the same. I can't change the node parameter into a double pointer. Thanks!
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include<conio.h>
typedef struct node {
int data;
struct node *next;
};
int main ()
{
struct node* first;
int temp,x,y;
struct node *create (struct node *first);
first = NULL;
void display (struct node *first);
printf ("\n\nCreating a Linked List\n");
printf ("\nEnter Element: ");
scanf ("%d", &x);
y=x;
while(y>0)
{
scanf ("%d", &x);
insert_sorted_linked_list(first,x);
y--;
}
printf ("\nThe list after creation is: ");
display (first);
printf ("\nThe sorted list is: ");
display (first);
return(0);
} /*END OF MAIN*/
insert_sorted_linked_list(struct node* head, int val)
{
struct node* pCur;
struct node* pNew = (struct node*) (malloc(sizeof(struct node)));
pNew -> data = val;
pNew ->next = NULL;
pCur = head;
if( pCur->data == NULL )
{
head->data = pNew->data;
head->next = NULL;
}
else if (pNew->data < pCur->data)
{
pNew ->next = pCur ;
head = pNew;
}
}
void display (struct node *first)
{ struct node *save; /*OR sort *save */
if (first == NULL)
printf ("\nList is empty");
else
{ save = first;
while (save != NULL)
{ printf ("-> %d ", save->data);
save = save->next;
}
getch();
}
return;
}
EDIT: Changed main to int. The debugger doesn't like the lines:
struct node* pNew = (struct node*) (malloc(sizeof(struct node)));
if( pCur->data == NULL )
Not sure what is wrong though.
EDIT 2:
I decided i wasn't going to get it working the original way he ask for it before tomorrow morning, so I went a modified version posted here. That one didn't seg fault, but it turns out there was a logic error as well.
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include<conio.h>
typedef struct s
{
int data;
struct s *next;
}node;
void insert_sorted_linked_list(node **head, int val);
void display (node **first);
void freeList(node **first);
int main ()
{
node* first;
int x,y;
first = NULL;
printf ("\n\nCreating a Linked List\n");
printf ("\nEnter number of elements: ");
scanf ("%d", &x);
y=x;
while(y>0)
{
scanf ("%d", &x);
insert_sorted_linked_list(&first,x);
y--;
}
printf ("\nThe sorted list is: ");
display (&first);
freeList(&first);
return 0;
}
void insert_sorted_linked_list(node **head, int val)
{
node* pCur;
node* pNew = (node*) (malloc(sizeof(node)));
pNew->data = val;
pNew->next = NULL;
pCur = (*head);
if( pCur == NULL )
{
(*head) = pNew;
}
else if(pNew->data < pCur->data)
{
pNew->next = pCur;
(*head) = pNew;
}
else
{
while(pCur->next!=NULL && pNew->data > pCur->next->data)
pCur = pCur->next;
pNew->next = pCur->next;
pCur->next = pNew;
}
}
void display (node **first)
{
node *lisprint; /*OR sort *lisprint */
if (*first == NULL)
printf ("\nList is empty");
else
{
lisprint = *first;
while (lisprint != NULL)
{
printf ("-> %d ", lisprint->data);
lisprint = lisprint->next;
}
getch();
}
} /*END OF FUNCTION DISPLAY*/
void freeList(node **first)
{
node *i;
i = *first;
while(i !=NULL)
{
(*first) = (*first)->next;
free(i);
i = *first;
}
}
Thanks!
Please properly format your code! It was a pain in the a** just to see where the error was!
As it is,
/*PROGRAM TO CREATE & THEN DISPLAY THE LINKED LIST IN SORTED FORM*/
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include<conio.h>
typedef struct s
{
int data;
struct s *next;
}node;
/* your declaration for typedef was incorrect. We use typedef in C for structures so that we do not have to repeat struct s everytime. Using typedef, we can write node as we do in c++ */
void insert_sorted_linked_list(node **head, int val); /* do not need to return anything, as well as see the parameter. When we want to change a pointer, we pass the address to the pointer, as it results in passing by value */
void display (node **first); /* same here and below */
void freeList(node **first); /* if you don't do this, memory leak!!! */
int main ()
{
node* first; /*OR sort *first,*list,*pass */
int temp,x,y;
first = NULL; /*OR sort *create() */
printf ("\n\nCreating a Linked List\n");
printf ("\nEnter number of elements: "); /* specify what you want the user to enter */
scanf ("%d", &x);
y=x;
while(y>0)
{
scanf ("%d", &x);
insert_sorted_linked_list(&first,x); /*CALLING CREATE FUNCTION, notice the &first*/
y--;
}
printf ("\nThe list after creation is: ");
display (&first);
printf ("\nThe sorted list is: ");
display (&first);
freeList(&first);
return 0;
} /*END OF MAIN*/
void insert_sorted_linked_list(node **head, int val)
{
node* pCur;
node* pNew = (node*) (malloc(sizeof(node)));
pNew->data = val;
pNew->next = NULL;
pCur = (*head);
if( pCur == NULL )
{
(*head) = pNew;
}
else if (pNew->data < pCur->data)
{
pNew->next = pCur ;
(*head) = pNew;
}
}
/*DISPLAY FUNCTION*/
void display (node **first)
{
node *save; /*OR sort *save */
if (*first == NULL)
printf ("\nList is empty");
else
{
save = *first;
while (save != NULL)
{
printf ("-> %d ", save->data);
save = save->next;
}
getch();
}
} /*END OF FUNCTION DISPLAY*/
void freeList(node **first)
{
node *i;
i = *first;
while(i !=NULL)
{
(*first) = (*first)->next;
free(i);
i = *first;
}
}

implementing stack with linked list in C

I'm having trouble implementing a Stack using a linked list with struct. The program compiles fine but when I run it, it prints the first element but then reads the next node as a NULL. I think it might be an error with my passing of the stack to the push method but I am not sure and I have not been successful in fixing it so I'm asking for your help:
#include <stdio.h>
#include <stdlib.h>
struct stackNode{
char data;
struct stackNode *nextPtr;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
void convertToPostfix(char infix[], char postfix[]);
int isOperator(char c);
int precedence(char operator1, char operator2);
void push(StackNodePtr *topPtr, char value);
char pop(StackNodePtr *topPtr);
char stackTop(StackNodePtr topPtr);
int isEmpty(StackNodePtr topPtr);
void printStack(StackNodePtr topPtr);
int main(){
convertToPostfix(NULL, NULL);
return 0;
}
void convertToPostfix(char infix[], char postfix[]){
StackNode stack = {'(', NULL};
StackNodePtr stackPtr = &stack;
push(stackPtr, 'a');
//printf("%s\n", stackPtr->data);
printStack(&stack);
}
void push(StackNodePtr *topPtr, char value){
StackNode *node;
node=(StackNodePtr)malloc(sizeof(StackNodePtr));
node->data=value;
node->nextPtr=*topPtr;
*topPtr=node;
}
void printStack(StackNodePtr topPtr){
if(topPtr == NULL){
printf("%s\n", "NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
return;
}
printf("%c\n", topPtr->data);
printStack(topPtr->nextPtr);
}
Any help would be appreciated.
Thanks
Several problems I could see:
1) printStack(&stack); should be printStack(stackPtr); as you are passing address of stackPtr to the push function.
2)
node = (StackNodePtr)malloc(sizeof(StackNodePtr));
should be:
node = malloc(sizeof(StackNode));
3)
push(stackPtr, 'a');
should be:
push(&stackPtr, 'a');
As you need to pass the address of the top pointer.
This is incorrect:
node=(StackNodePtr)malloc(sizeof(StackNodePtr));
as it is only allocating memory for a struct stackNode* (commonly 4-bytes for any pointer type), when it should be allocating memory for a struct stackNode (at least 5 bytes):
node = malloc(sizeof(StackNode));
--
See Do I cast the result of malloc?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node * link;
};
void push(struct node **, int);
int pop(struct node **);
void display(struct node *);
void printMenu();
int main() {
struct node * p;
p = NULL;
int data, ch, data1;
//char choice[10];
do {
printMenu();
printf("Enter your choice\n");
scanf("%d", &ch);
switch (ch) {
case 1:
printf("Enter the element to be pushed\n");
scanf("%d", &data);
push(&p, data);
break;
case 2:
data1 = pop(&p);
if (data1 != -1000)
printf("The popped element is %d\n", data1);
break;
case 3:
printf("The contents of the stack are");
display(p);
printf("\n");
break;
default:
return 0;
}
} while (1);
return 0;
}
void printMenu() {
printf("Choice 1 : Push\n");
printf("Choice 2 : Pop\n");
printf("Choice 3 : Display\n");
printf("Any other choice : Exit\n");
}
void push(struct node **q, int num) {
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->link = (*q);
temp->data = num;
(*q) = temp;
}
void display(struct node *q) {
//Fill in the code here
struct node *temp = q;
if (temp == NULL)
printf(" {}");
while (temp != NULL)
{
printf(" %d", temp->data);
temp = temp->link;
}
}
int pop(struct node **q) {
//Fill in the code here
struct node *temp;
int item;
if (*q == NULL)
{
printf("Stack is empty\n");
return -1000;
}
temp = *q;
item = temp->data;
*q = (*q)->link;
free(temp);
return item;
}

LinkedList Elements Swap Problem In C

I wrote a program that has many functionalities but I can not swap 2 elements of 2 nodes in the linked list.Actually I can swap 2 nodes by changing their links but I can not swap 2 elements when the user requested 2 elements swapping.Here is my code without any swap operation.Again I have to say I want to do this swap operation by swapping 2 node elements not changing node links.How can I get rid of this problem?Any help will be appreciated.
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *next;
};
typedef struct node nodetype;
void insert(int ,struct node **);
void display(struct node *);
void search(int, struct node *);
void delete(int, struct node **);
int main(void){
nodetype *p;
p=NULL;
int x=0,choice;
int s_no,k,r_no;
while(x!=1){
printf("enter 1 for insert\n");
printf("enter 2 for display\n");
printf("enter 3 for search\n");
printf("enter 4 for delete\n");
printf("enter 0 for exit\n");
fflush(stdout);
scanf("%d",&choice);
if(choice==1){
printf("enter inserted no\n");
fflush(stdout);
scanf("%d",&k);
insert(k,&p);
}
else if(choice==2)
display(p);
else if(choice==3){
printf("enter searched no\n");
scanf("%d",&s_no);
search(s_no, p);
}
else if(choice==4){
printf("enter deleted no\n");
scanf("%d",&r_no);
delete(r_no,&p);
}
else
printf("invalid choice\n");
}
return 0;
}
void display ( struct node *p)
{
printf("the content is:\n");
if(p==NULL)
printf("the link is empty\n");
while ( p != NULL )
{
printf ( "%d ", p -> data ) ;
p = p -> next ;
}
printf ( "\n" ) ;
}
void search(int no, struct node *p){
nodetype * loc;
for(loc=p;loc!=NULL;loc=loc->next)
{
if(no==loc->data){
printf("\nthe number exist in the list\n");
return;
}
}
printf("\nthe number is not exist in the \n");
}
void insert(int x,struct node **p)
{
struct node *r,*temp=*p;
r = (struct node *)malloc ( sizeof (struct node)) ;
r ->data = x ;
r->next=NULL;
if ( *p == NULL)
{
*p = r ;
}
else
{
while(temp->next!= NULL)
{
temp=temp->next;
}
temp->next=r;
}
}
void delete(int num, struct node **p){
struct node *temp,*x;
temp=*p;
x= NULL;
while (temp->next !=NULL){
if(temp->data == num)
{
if (x==NULL)
{
*p = temp->next;
free(temp);
return;
}
else
{
x->next = temp->next;
free(temp);
return;
}
}
x=temp;
temp=temp->next;
}
printf(" No such entry to delete ");
}
I attempted swap operation with using
user entered numbers.For instance,the
user entered 12 and 45 in order to
swap in the linkedlist.How can I do
that?
I would suggest you extend the existing function with return values, (not tested just the idea)
nodetype * search(int no, struct node *p){
nodetype * loc;
for(loc=p;loc!=NULL;loc=loc->next)
{
if(no==loc->data){
printf("\nthe number exist in the list\n");
return loc;
}
}
printf("\nthe number is not exist in the \n");
return NULL;
}
After that you call search for both values entered by the user.
Then you swap the values in place without changing any pointer references simply be assigning new values. Of course you need to check whether the nodes were actually found (not NULL).
nodetype *node1;
nodetype *node2;
node1 = search( userInput1, &p );
node2 = search( userInput2, &p );
int tmp_data = node1->data;
node1->data = node2->data;
node2->data = tmp;

Resources