This is a program to print two link lists using one function.
I have used two functions i.e create and display.Create() is to create the linklist and display() to display the result of linklist.
But this code is printing NULL. I'm not not getting where is the error???
`#include<stdio.h>
#include<conio.h>
struct node
{
int data;
struct node* next;
}
*start=NULL,*start1=NULL;
//to create the linklist
struct node* create(struct node* ptr)
{ int ch;
do
{
struct node* new_node=(struct node*)malloc(sizeof(struct node));
struct node* current;
printf("enter the data\n");
scanf("%d",&new_node->data);
new_node->next=NULL;
if(ptr==NULL)
{
ptr=new_node;
current=new_node;
}
else
{
current->next=new_node;
current=new_node;
}
printf("Do u want to add more ");
scanf("%d",&ch);
}while(ch!=0);
return ptr;
}
//to display the linklist
void display(struct node* temp)
{
while(temp!=NULL)
{
printf("%d--->",temp->data);
temp=temp->next;
}
printf("NULL\n");
}
int main()
{
clrscr();
create(start);
display(start);
printf("\n 2nd linklist\n");
create(start1);
display(start1);
getch();
return 0;
}
First problem
current must be declared outside the do/while loop, otherwise you will get undefined behaviour because there is no guarantee that current will keep it'svalue from one iteration to the next. However with certain compilers you may get away with it.
Second problem
Calling create(start); will not modify start because variables in C are passed by value. You need to write start = create(start);. See also this SO question. In your program start is still NULL after the call to the create function. You could have found out that easily by yourself.
Related
When I run the following code, it gives me an infinite looping result. However if I comment out the free pointer lines in the insert function i.e. free(ptr) and free(ptrnext) then it works fine. Can anybody explain why is it so?
I am pretty sure that the print and takeInput works fine, and hence can be ignored.
#include<stdio.h>
#include<stdlib.h>
typedef struct Nodes{
struct Nodes * next;
int val;
}Node;
//Function to create a linked list
Node * takeInput(){
int data;
Node *start =NULL ;
Node *tail=NULL;
printf("Enter the number of nodes");
int num,i;
scanf("%d",&num);
for(i=1;i<=num;i++){
if(start==NULL){
start=malloc(sizeof(Node));
puts("Enter data");
scanf("%d",&data);
start->val=data;
start->next=NULL;
tail=start;
}
else{
Node * ptr = malloc(sizeof(Node));
puts("Enter data" );
scanf("%d",&data);
ptr->val=data;
tail->next=ptr;
tail=tail->next;
}
}
tail->next=NULL;
return start;
}
//Function to print
void print(Node * head){
Node*ptr=head;
while(ptr!=NULL){
printf("%d->",ptr->val);
ptr=ptr->next;
}
}
//Function to insert a node in given linked list
Node * insert(Node *start){
int i,data;
puts("Enter pos");
scanf("%d",&i);
puts("Enter data");
scanf("%d",&data);
Node * ptr=malloc(sizeof(Node));
ptr->val=data;
ptr->next=NULL;
if(i==1){
ptr->next=start;
start=ptr;
free(ptr);
}
else{
Node * ptrnext=start;
while(i!=1){
ptrnext=ptrnext->next;
i--;
}
ptr->next=ptrnext->next;
ptrnext->next=ptr;
free(ptr);
free(ptrnext);
}
return start;
}
int main(void){
Node * start =takeInput();
start=insert(start);
print(start);
}
When I run the following code, it gives me an infinite looping result. However if I comment out the free pointer lines in the insert function i.e. free(ptr) and free(ptrnext) then it works fine.
This is undefined behavior. (when you don't comment the free() functions)
Once you've freed memory you must remember not to use it any more.
Note : the pointer might or might not point the same block after freeing, it's undefined behavior
so don't free the pointer unless you want to destroy or delete the node.
so don't use the free() in the insert function as you are not deleting any node.
Apart from that, I don't see any function to deallocate the memory at the end of the program.
Always make sure to deallocate the allocated memory at the end using a delete() function.
Here's a typical implementation of delete function
void delete(Node* start)
{
Node* temporary = NULL;
while(start != NULL)
{
temporary = start->next; //saving next node address
free(start); //freeing current node
start = temporary; //assigning start with next node address
}
printf("successfully destroyed the list!"); //function exit message
}
Call it at the end of main() function or when you wish to delete the entire list
I'm trying to make link list which represents polynomial.
Each node consists of coefficient,power of x,link to the next node
I have tried this program without passing arguments it worked .
but when when tried passing arguments the link list isn't being created.
pls help to rectify my program..
*****THIS IS MY PROGRAM WITH STRUCTURE POINTERS AS AN
ARGUMENT IN THE INSERT FUNCTION*****
#include<stdio.h>
#include<stdlib.h>
struct node
{
float coff;
int expo;
struct node *next;
};
struct node *start1=NULL,*current1=NULL;
void insert(struct node *start,struct node *current)
{
struct node *new_node;
new_node=(struct node*)malloc(sizeof(struct node));
if(start==NULL)
{
start=new_node;
current=new_node;
}
else
{
current->next=new_node;
current=new_node;
}
printf("\nEnter coefficient:");
scanf("%f",&new_node->coff);
printf("\nEnter power of x:");
scanf("%d",&new_node->expo);
new_node->next=NULL;
}
void show(struct node *start)
{
struct node *ptr;
ptr=start;
while(ptr!=NULL)
{
printf(" %.2fx^%d",ptr->coff,ptr->expo);
ptr=ptr->next;
}
}
void find(float scoff,int sexpo,struct node *start)
{
//scoff=search coefficient, sexpo=search exponent
int flag=0;
struct node *ptr;
ptr=start;
while(ptr!=NULL)
{
if(ptr->coff==scoff && ptr->expo==sexpo)
{
printf("your term found-> %.1fx^%d",ptr->coff,ptr->expo);
flag=1;
break;
}
else
ptr=ptr->next;
}
if(flag==0)
printf("\nSorry term couldn't be found!!");
else
printf("\nSearch success!!");
}
int main()
{
int c=1,ex=0;
float cf=0;
while(1)
{
insert(start1,current1);
printf("\nWant to continue(1/0)?");
scanf("%d",&c);
if(c==0)
break;
}
show(start1);
while(1)
{
printf("\nEnter coff and expo respectively:");
scanf("%f%d",&cf,&ex);
find(cf,ex,start1);
printf("\nWant to continue(1/0)?");
scanf("%d",&c);
if(c==0)
break;
}
return 0;
}
The problem is that you're modifying a local copy of the start and current pointers (i.e. the copies passed as the function arguments), thus not actually changing the linked list. You should instead modify the start1 and current1 pointers. There's no need for the insertion function to take start and current parameters as it can simply modify the global variables. (I should note that this is a bad design choice.)
More specifically, the problem is when initializing the list in
if (start==NULL)
{
start=new_node;
current=new_node;
}
you only modify the local copy that gets destroyed when it goes out of scope. So start1 and current1 are still NULL after the function returns.
Change the insert function to
void insert(struct node *start,struct node *current)
{
struct node *new_node;
new_node=(struct node*)malloc(sizeof(struct node));
if(start1==NULL)
{
start1=new_node; // You previously had start instead of start1
current1=new_node; // You previously had current instead of current1
}
else
{
current1->next=new_node;
current1=new_node;
}
printf("\nEnter coefficient:");
scanf("%f",&new_node->coff);
printf("\nEnter power of x:");
scanf("%d",&new_node->expo);
new_node->next=NULL;
}
Beware: after this modification, you can call insert() (i.e. no need for insert to have parameters) as the function will operate on the global variables. The other option---better, but more time-consuming---is to somehow initialize the linked list and then use the functions in their current form (except for minor modifications).
I am unable to append a new node in the linked list. I have already identified the problem area but after much research and trying many things I am still unable to resolve the issue.
The problem is with the for loop in insert_node(char,struct **) function and traverse(struct *) function both of which never seem to terminate:
// program that stores name of the user using linkedlist
#include<stdio.h>
#include<stdlib.h>
typedef struct LIST{
int flag;
char name;
struct LIST *next;
} LISTNODE;
LISTNODE *head=NULL,*newnode=NULL;// global pointers
LISTNODE* initialize(); //initializes struct node with default values and returns a node
void insertNode(char c,LISTNODE** temp);
void traverselist(LISTNODE *temp);
int main(){
char ans,ch;
printf("\n\nEnter your name and hit enter-\n\n");
do{
printf("your name:");
fflush(stdin);
scanf("%c",&ch);
insertNode(ch,&head);
printf("\n\ninsertnode-back to main()");
printf("Want to continue?(Y?N):");
fflush(stdin);
scanf("%c",&ans);
}while(ans=='y'||ans=='Y');
printf("\n\ntraverselist-leaving main()");
traverselist(head);
printf("\n\ntraverselist-back to main()");
return 0;
}
void insertNode(char c, LISTNODE **temp){
printf("\n\ninto insertnode: before initialize");
LISTNODE* temp2;
newnode=initialize();
printf("\n\nback to insertnode:after initialize");
//printf("\nnewnode->name=%c",newnode->name);
//printf("\nnewnode->flag=%d",newnode->flag);
newnode->name=c;
//printf("\nnewnode->name=%c",newnode->name);
//printf("\nnewnode->flag=%d",newnode->flag);
//for(;(*temp)!=NULL;temp=&(*temp)->next);
/*while((*temp)->next!=NULL){
temp=&(*temp)->next;
printf("\n\nIn while!");
}
*/
for(;*temp!=NULL;temp=&((*temp)->next))
printf("\n\nIn for!") ;
//printf("\n\nout of while!");
(*temp)=newnode;
}
LISTNODE* initialize(){
static int count=0;
LISTNODE *tempnewnode;
printf("\n\nINto inintialize!");
tempnewnode=(LISTNODE*)malloc(sizeof(LISTNODE));
if(tempnewnode==NULL){
printf("No memory available. Aborting!");
exit(0);
}
else{
tempnewnode->flag=0;
tempnewnode->name='*';
tempnewnode->next=NULL;
if(count==0){
head=tempnewnode;
count++;
}
}
return tempnewnode;
}
void traverselist(LISTNODE *temp){
printf("\n");
for(;temp!=NULL;temp=temp->next){
printf("%c",temp->name);
}
}
Please help!
The problem is inside the insert_node function, specifically with the loop:
for(;*temp!=NULL;temp=&((*temp)->next))
printf("\n\nIn for!");
You'd be better advised not to use the reference temp in your loop, as it overwrites the head->next back to itself. Create another temporary pointer.
I changed the insertNode(char, LISTNODE**) to the following:
void insertNode(char c, LISTNODE *temp){
LISTNODE** temp2=&temp;
newnode=initialize();
printf("\n\nback to insertnode:after initialize");
newnode->name=c;
for(;(*temp2)!=NULL;temp2=&(*temp2)->next)
printf("\n\nIn for!") ;
(*temp2)=newnode;
}
and function is called like this:
insertNode(ch,head);
It works just fine!
The problem is this portion of your insertNode function
for(;*temp!=NULL;temp=&((*temp)->next))
printf("\n\nIn for!") ;
//printf("\n\nout of while!");
(*temp)=newnode;
Here you should first check if the link list is empty or not if it is empty then you can create the new node and assign the address of it to temp.
If not then depending upon whether you want to insert the new element in the end, beginning or middle of the list you should traverse the list then perform the insertion.
For example if you want to perform insertion at the beginning then after creating the new node you should assign the address of the start pointer of the list to the next of newly created node and move the start to the new node as you have to keep track of the start pointer.
In this code below, when I comment out the first and second call to display() function in main, It works fine. But without commenting, after adding 2nd element it says - segmentation fault.
I am new to pointers. Please suggest what might be wrong.
#include<stdio.h>
#include<malloc.h>
//-------------------------------------------------
struct node
{
int data;
struct node *next;
}*start=NULL;
//------------------------------------------------------------
void creat()
{
struct node *new_node,*current;
new_node=(struct node *)malloc(sizeof(struct node));
printf("\nEnter the data : ");
scanf("%d",&new_node->data);
new_node->next=NULL;
if(start==NULL)
{
start=new_node;
current=new_node;
}
else
{
current->next=new_node;
current=new_node;
}
}
//------------------------------------------------------------------
void display()
{
struct node *new_node;
printf("\nThe Linked List : ");
new_node=start;
while(new_node!=NULL)
{
printf("%d--->",new_node->data);
new_node=new_node->next;
}
printf("NULL\n\n");
}
//----------------------------------------------------
void main()
{
creat();
display();
creat();
display();
creat();
display();
}
output ->
$./a.out
Enter the data : 4
The Linked List : 4--->NULL
Enter the data : 6
Segmentation fault (core dumped)
This is happening because of current->next=new_node; in else block.
When you enter data second time start is declared global so its value persists between function call but as current is declared within fuunction it's scope is limited to function only.
So when you enter data second time current is null so accessing current->next causes segmentation fault.
So declare current node after start variable.
Second time you call creat, you are using an ininitialized current.
current_node is a local variable with auto storage. When you return from the function, it gets deleted.
Try adding
struct node* current = NULL;
right after you define start. Then, remove it from creat.
The offending code is:
current->next=new_node;
You are dereferencing a NUll pointer which is illegal.
What you should have done was to declare current as a global variable as well:
struct node
{
int data;
struct node *next;
}*start=NULL,*current=NULL;
This will fix your display issue as well.
I am working on a simple text editor in C. I am having troubles with inserting an element in a linked list.
Here is my structure:
struct node {
struct node *previous;
int c;
int x;
int y;
struct node *next;
}*head;
Here is my insertion code:
void checker(int ch, int xpos, int ypos)
{
int flag=0;
struct node *temp,*temp1,*insert_node=NULL;
temp=(struct node *)malloc(sizeof(struct node));
temp=head;
while(temp!=NULL)
{
if(temp->x==xpos && temp->y==ypos)
{
insert_node->c=ch;
insert_node->x=xpos;
insert_node->y=ypos;
if(temp->previous==NULL) //this is for inserting at the first
{
insert_node->next=temp;
head=insert_node;
}
else //this is for inserting in the middle.
{
temp1=temp;
temp=insert_node;
insert_node->next=temp1;
}
flag=1;
break;
}
temp=temp->next;
}
//this one's for the normal insertion and the end of the linked list.
if(flag==0)
characters(ch,xpos,ypos);
}
None of the inserting in the first and middle works. I do not know where it went wrong. Please help me.
temp=(struct node *)malloc(sizeof(struct node));
temp=head;
You are allocating space for a new node, but then you loose the address of this new node assigning temp=head.
The problem is that insert_node is a local variable in your function checker() which is also initialized as NULL. Doing insert_node->c means NULL->c which i'm sure you'll agree with me that is wrong.
Try to dynamically allocate memory for your variables before using them and you should be fine.
insert_node will always be NULL in the code you posted.
Also, you may want to split your code more; start by isolating part of it in a find() function.