Creating struct using pointer - c

Im working on a program that creates a structure with functions for adding and displaying new nodes. I have a function called "add" and I use it to create new nodes and send them to struct->next but whenever I try to run my function "displayData", the function says that my structure is NULL/empty.
Here is the code.
#include <stdio.h>
#include <stdlib.h>
typedef struct node *nodePtr;
struct node {
int item;
nodePtr next;
};
typedef nodePtr Statistician;
int input();
Statistician newStatistician(); //allocates memory to the structure. Dynamic allocation
void add(Statistician s, int x); //Adds data to the rear
void displayData(Statistician s); //prints entire dataset
int main() {
int operation, data;
Statistician s = NULL;
data = input(); //get new input
add(s,data); //run add function
displayData(s); //run display function
}
int input(){
int x;
printf("Enter data: ");
if (scanf("%d", &x) != 1)
{
printf("\n\nInvalid Input!\n\n");
exit(0);
}
return x;
}
Statistician newStatistician(){
Statistician newStat;
newStat = malloc(sizeof(struct node));
return newStat;
}
void add(Statistician s, int x){
Statistician newNode = newStatistician();
newNode->item = x;
newNode->next = NULL;
if(s == NULL){
s = newNode;
return;
}
while (s != NULL) {
s = s->next;
}
s->next = newNode;
}
void displayData(Statistician s){
Statistician temp = s;
if(s==NULL){
printf("\n\nList is EMPTY.");
printf( "\n\nPress any key.\n" );
getch();
return;
}
printf( "\n\nThe List:\n" );
while (temp != NULL) {
printf(" %d", temp->item);
temp = temp->next;
}
printf( "\n\nPress any key.\n" );
getch();
return;
}
When i use displayData, the output is.
List is EMPTY

You have to pass the head node by reference. Otherwise the functions that change the list will deal with a copy of the head node and the original head node will not be changed.
For example
void add(Statistician *s, int x)
{
Statistician newNode = newStatistician();
newNode->item = x;
newNode->next = NULL;
while ( *s != NULL ) s = &( *s )->next;
*s = newNode;
}
And the function can be called like
add( &s, data );

Related

Keep printing the last element in the linked list

I created a standard linked list in C. It asks the user to input a number, and program end if user input #. If the user inputs anything else the program will stop.
The problem is that my program runs forever and prints the normal list at first then keeping print the last element of the linked list.
Hope someone could tell me where did I made mistake.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} NodeT;
void freeLL(NodeT *list) {
NodeT *p, *temp;
p = list;
while (p != NULL) {
temp = p->next;
free(p);
p = temp;
}
}
void showLL(NodeT *list) {
NodeT *temp = list;
temp = temp->next;
printf("Done. The list is ");
printf("%d", temp->data);
temp = temp->next;
//iterate the entire linked list and print the data
while (temp != NULL) {
printf("-->");
printf("%d", temp->data);
temp = temp->next;
}
}
NodeT *joinLL(NodeT *list, int v) {
NodeT *current = list;
NodeT *head;
head->data = v;
head->next = NULL;
while (current->next != NULL) {
current = current->next;
}
current->next = head;
return head;
}
int main() {
int data;
NodeT *list = NULL;
list = (NodeT *)malloc(sizeof(NodeT));
printf("Enter a number: ");
if (scanf("%d", &data) != 1) {
printf("Done. ");
} else {
printf("Enter a number: ");
joinLL(list, data);
while (1 == scanf("%d", &data)) {
printf("Enter a number: ");
joinLL(list, data);
}
showLL(list);
freeLL(list);
}
return 0;
}
I believe the problem is in the joinLL function which add a new node at the end of the linked list.
The problem is you do not allocate elements in joinLL: only a single element in allocated in main().
You should instead always allocate the element in joinLL and update the head pointer from the return value.
Similary, freeLL should take a pointer to head and set it to NULL for consistency.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} NodeT;
void freeLL(NodeT *p) {
while (p != NULL) {
NodeT *temp = p->next;
free(p);
p = temp;
}
}
void showLL(const NodeT *list) {
NodeT *p = list;
printf("The list is ");
if (p == NULL) {
printf("empty");
} else {
printf(" %d", temp->data);
while ((p = p->next) != NULL) {
printf("--> %d", temp->data);
}
}
printf("\n");
}
NodeT *joinLL(NodeT *head, int v) {
NodeT *newp = malloc(sizeof(*p));
NodeT *current;
if (newp == NULL) {
fprintf(stderr, "allocation failure\n");
exit(1);
}
newp->data = v;
newp->next = NULL;
if (head == NULL) {
return newp;
}
for (current = head; current->next != NULL; current = current->next)
continue;
current->next = newp;
return head;
}
int main() {
NodeT *list = NULL;
for (;;) {
int data;
printf("Enter a number: ");
if (scanf("%d", &data) != 1) {
printf("Done. ");
break;
}
list = joinLL(list, data);
}
showLL(list);
freeLL(list);
return 0;
}
Your program keeps running because of a memory access error, you did not allocate memory for your head(you set a pointer, but use it directly without initializing it)
Change to this may solve the problem:
head=(NodeT*)malloc(sizeof(NodeT));
if(NULL==head)
{
// failed : do something...
return NULL;
}
head->data=v;
head->next=NULL;
When I just tested it, I found that there was another problem:
list = (NodeT*)malloc(sizeof(NodeT));
malloc will not be initialize your list, so the value that your list->next initially points to is uncertain.
in c, malloc does not need to be cast.

Segmentation Fault on Linked List Using C

I am new to C and try to learn how to implement C on linked list. I am really confused why I can't access myList in the main function? because when I try to myList->data, it's segmentation fault. I think there's some error in my addtohead function?
Below is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct NODE{
int data;
struct NODE *next;
}node;
node * myList;
node * addToHead(node*, int);
void printList();
int main(){
myList = NULL;
int input;
while (scanf("%i",&input) == 1){
addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
void printList(node* head){
node *temp = head;
while(temp != NULL){
printf("%d ", temp->data);
temp = temp -> next;
}
printf("\n");
}
Your addToHead function is supposed to return the mallocated memory back to caller.
So you should assign the return value to mylist at first:
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1){
myList = addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
Into your addToHead function you wrote
head = temp;
But head has local scope and the assigned value is not reflected to the pointer myList.
To do so you have to use pointer to pointer.
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1)
{
if (addToHead(&myList, input) == true)
{
printf("%d \n", myList->data);
}
else
{
fprintf(stderr, "Error addToHead\n");
}
}
return 0;
}
bool addToHead(node** head, int newData){
node *temp = malloc(sizeof(node));
if (temp != NULL)
{
temp -> data = newData;
temp -> next = NULL;
if(head != NULL)
{
temp -> next = *head;
}
*head = temp;
return true;
}
return false;
}
Finally always remember to check the malloc return value: it can fail.
You return the new head node from addToHead, but you don't do anything with it. You need to assign this value to myList to update it:
myList = addToHead(myList, input);
Also, you misspelled a variable on the following line:
printf("%d \n", myListd->data);
It should be:
printf("%d \n", myList->data);
In this function definition
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
The parameter node* head is a local variable of the function. Any changes of the parameter will not influence on the original argument. The function parameters will be destroyed after exiting the function.
You can consider the function definition and its call the following way
addToHead(myList, input);
//...
node* addToHead(/*node* head, int newData*/){
node *head = myList;
int newData = input;
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
So the original variable myList will not be changed after the function call. You have to assign explicitly the returned value to the variable
myList = addToHead(myList, input);
Also the function has a drawback. It does not report an error in case when the new node was not allocated.
A better approach to write the function looks the following way
int /* _Bool */ addToHead( node **head, int newData )
{
node *temp = ( node * )malloc( sizeof( node ) );
int /* _Bool */ success = temp != NULL;
if ( success )
{
temp -> data = newData;
temp -> next = *head;
*head = temp;
}
return success;
}
In this case the function can be called in a loop the following way
while ( scanf( "%i", &input ) == 1 && addToHead( &myList, input ) )
{
//...
}

Create two linked lists using one function

I have a function called ll() for creating a linked list as follows. My program requires two linked lists. Is it possible to reuse this function so I can have two linked lists, say head1 and head2?
#include <stdio.h>
#include <malloc.h>
typedef struct node
{
int data;
struct node* link;
} Node;
Node* head = NULL;
Node* previous = NULL;
int main(void)
{
ll();
print();
return 0;
}
int ll()
{
int data = 0;
while(1)
{
printf("Enter data, -1 to stop: ");
scanf("%d", &data);
if(data == -1)
break;
addtoll(data);
}
}
int addtoll(int data)
{
Node* ptr = NULL;
ptr = (Node*)malloc(sizeof(Node));
ptr->data = data;
ptr->link = NULL;
if(head == NULL)
head = ptr;
else
previous->link = ptr;
previous = ptr;
}
int print()
{
printf("Printing linked list contents: ");
Node* ptr = head;
while(ptr)
{
printf("%d ", ptr->data);
ptr = ptr->link;
}
printf("\n");
}
Is there a better way than doing something like
main()
{
ll(1);
ll(2);
}
int ll(int serial)
{
if (serial == 1)
Use head1 everywhere in this function
else if(serial == 2)
Use head2 everywhere in this function
}
Instead of passing an int you could also just pass the linked list.
Node head1;
Node head2;
Node previous1;
Node previous2;
int main(){
ll(&head1, &previous1);
ll(&head2, &previous2);
}
int ll(Node* head, Node* previous)
{
int data = 0;
scanf("%d",&data);
*head = {data, null};
previous = head;
while(1)
{
printf("Enter data, -1 to stop : ");
scanf("%d",&data);
if(data == -1)
break;
addtoll(data, previous);
}
}
int addtoll(int data, Node* previous)
{
struct student newNode = {data, null}
previous->link = &newNode;
previous = &newNode;
}
Exceutable Code to implement more than 1 Linked List by appending new node one by one.

Printing strings in linked lists

So I'm having trouble getting my program to print both the strings I input, or however many you want to put in the list, it always prints out the last string inputted multiple times. I am sorry about all the commented out code, most of it you don't need to read.
#include<stdio.h>
#include<stdlib.h>
struct node{
char *data;
struct node *next;
}*head;
typedef struct node NODE;
// Function prototypes
void append(char myStr[]);
void add( char myStr[] );
//void addafter(char myStr[], int loc);
void insert(char myStr[]);
int delete(char myStr[]);
void display(struct node *r);
int count();
// main function
int main()
{
int i;
struct node *n;
head = NULL;
char myStr[50];
while(1)
{
printf("\nList Operations\n");
printf("===============\n");
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Size\n");
printf("4.Delete\n");
printf("5.Exit\n");
printf("Enter your choice : ");
if(scanf("%d", &i) <= 0)
{
printf("Enter only an Integer\n");
exit(0);
}
else
{
switch(i)
{
case 1:
printf("Enter the name to insert : ");
scanf("%50s", myStr);
insert(myStr);
break;
case 2:
if(head == NULL)
{
printf("List is Empty\n");
}
else
{
printf("Name(s) in the list are : ");
}
display(n);
break;
case 3:
printf("Size of the list is %d\n",count());
break;
case 4:
if(head == NULL)
printf("List is Empty\n");
else
{
printf("Enter the myStrber to delete : ");
scanf("%50s",myStr);
if(delete(myStr))
printf("%s deleted successfully\n",myStr);
else
printf("%s not found in the list\n",myStr);
}
break;
case 5:
return 0;
default:
printf("Invalid option\n");
}
}
}
return 0;
}
// Function definitions
void append(char myStr[])
{
struct node *temp,*right;
temp = (struct node *)malloc(sizeof(struct node));
temp->data = myStr;
right=(struct node *)head;
while(right->next != NULL)
{
right = right->next;
}
right->next = temp;
right = temp;
right->next = NULL;
}
// adding a node to the beginning of the linked list
void add( char myStr[] )
{
struct node *temp;
temp =(struct node *)malloc(sizeof(struct node));
temp->data = myStr;
// only one node on the linked list
if (head == NULL)
{
head = temp;
head->next = NULL;
}
else
{
temp->next = head;
head = temp;
}
}
void insert(char myStr[])
{
int c = 0;
struct node *temp;
temp = head;
if(temp == NULL)
{
add(myStr);
}
else
{
append(myStr);
}
}
int delete(char myStr[])
{
struct node *temp, *prev;
temp = head;
while(temp != NULL)
{
if(temp->data == myStr)
{
if(temp == head)
{
head = temp->next;
head = (*temp).next;
free(temp);
return 1;
}
else
{
prev->next = temp->next;
free(temp);
return 1;
}
}
else
{
prev = temp;
temp = temp->next;
}
}
return 0;
}
void display(struct node *r)
{
r = head;
if(r == NULL)
{
return;
}
while(r != NULL)
{
printf("%s ", r->data);
r = r->next;
if(r == NULL)
{
printf("\nOur linked list is finished!");
}
}
printf("\n");
}
int count()
{
struct node *n;
int c = 0;
n = head;
while(n != NULL)
{
n = n->next;
c++;
}
return c;
}
The problem seems to be that myStr at main function is a char[], so it's content is overritten every time you insert data. Notice that struct node data field is a char*, it's just pointing to myStr address.
Hope this help!
Your program has only one place to write your input, myStr.
With each input, myStr is erased and a something else is written to myStr.
The data member of all of the nodes, points to myStr. myStr will only contain the last input.
The display() function asks each node what is data. data points to myStr so each node prints the contents of myStr. myStr will only contain the last input so all the nodes print the last input.
To fix this, in the add() and append() functions, you need to give the data member some memory by using malloc(). Then copy the contents of myStr to the data member by using strcpy().
temp->data = malloc ( strlen ( myStr) + 1);
strcpy ( temp->data, myStr);
Do this instead of temp->data = myStr;
You will need #include<string.h>
The memory will need to be free()'d in the delete() function.
free(temp->data);
Do this before freeing temp
char *data
that variable from struct is always assigned with the address of myStr as its a pointer it would only show you the value of myStr

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;
}
}

Resources