I have written my first datastructures code in C and I am baffled as to what I am doing wrong. I am just trying to add a node to the front of the linked list or to an empty linked list and print the list at the end and it is resulting in segmentation fault.
#include<stdio.h>
#include<stddef.h>
#include<cstdlib>
/* Node representing each node of the linked list */
struct Node {
int data;
struct Node *next;
};
/* Fist node is always null as there are no nodes in the linked list to begin with */
struct Node *first = NULL;
void add_node(int data) {
struct Node *newptr = (Node *)malloc(sizeof(Node));
// Check if the list is empty
if (first == NULL){
printf("The list is empty\n");
newptr->data = data;
newptr->next = NULL;
first = newptr;
}
else {
printf("Adding to the existing list\n");
printf("Data in the first node is %d",first->data);
}
}
void display() {
struct Node *ptr;
printf("In the display function\n");
ptr = first;
do {
printf("Printing the data in the node %d",ptr->data);
ptr= ptr->next;
}while(ptr->next != NULL);
}
int main() {
/*
* Just try and add one node
*/
int y = 100;
printf("Adding a node \n");
add_node(y);
display();
return 1;
}
I messed up the display function, I changed it a bit to have the correct output.
The following is the new display function:
void display(struct Node *first) {
struct Node *ptr;
printf("In the display function\n");
ptr = first;
do {
printf("Printing the data in the node %d",ptr->data);
ptr= ptr->next;
}while(ptr != NULL);
}
Related
I'm stuck in a while loop (the one that prints "no" ):
#include<stdlib.h>
#include<stdio.h>
typedef struct bill {
int value;
struct bill *next;
} list;
void printlist(list *head) {
list *temp = head;
while (temp != NULL)
printf("%d ",temp->value), temp = temp->next;
}
void insert_at_end(list *head, int value) {
list *current, *first;
first = malloc(sizeof(list));
if (head == NULL)
head = first;
else {
current = head;
while (current->next != NULL) {
current = current->next;
printf("no");
}
}
}
void main() {
list *head = NULL;
head = malloc(sizeof(list));
for (int i = 0; i < 10; i++)
insert_at_end(head, i);
printlist(head);
}
I'm not sure why, but current never gets to NULL. I watched numerous videos and they all do the same:
while (current != NULL)
current = current->next
...which should just get to NULL at one point, but it doesn't in my case.
There are these issues:
When you do head = malloc(sizeof(list)), the members of that node are still undefined, including its next member. As a consequence, when you get into the else block in the insert_at_end function, the loop will access this undefined next pointer and bring about undefined behaviour.
Similar to the previous problem, also first does not get initialised with a value and a next member.
In the else block in the insert_at_end function there is no code that attaches the new node to the list.
In the if block in the insert_at_end function, the value of head is altered. But this just changes the value of a local variable -- the caller will not see this change. For that to happen you should alter the function parameter so that it is a pointer to the head pointer.
The creation of a head node in the main program seems unwaranted -- you should start with an empty list, i.e. with head equal to NULL.
void main is not correct. It should be int main, and the appropriate value should be returned by it.
Here is the correction to the two functions that have issues:
// This function accepts a pointer to a head-pointer, so the head-pointer
// can be changed and the caller will receive that change.
void insert_at_end(list **head, int value){
list *current, *first;
first = malloc(sizeof(list));
first->value = value; // This was missing
first->next = NULL; // This was missing
if (*head == NULL) {
*head = first;
} else {
current = *head;
while (current->next != NULL) {
current = current->next;
}
current->next = first; // This was missing
}
}
// The main method has an int return type
int main() {
list *head = NULL;
// Do not create a node here.
for (int i = 0; i < 10; i++) {
insert_at_end(&head, i); // pass pointer to head-pointer
}
printlist(head);
return 0;
}
I need to write a function that inserts a new node in a singly linked list, between every two existing nodes, with a value that is equal to the difference of the values of those two nodes.
For example if we have list 1→2→5→7 the result should be 1→1→2→3→5→2→7, because 2-1=1, 5-2=3 and 7-5=2.
Here is my attempt:
struct Node{
int v;
struct Node* next;
};
void insert(struct Node** headPtr){
struct Node* curr = *headPtr;
struct Node* new = malloc(sizeof(struct Node));
while(curr->next!=NULL){
new->v=curr->next->v-curr->v;
new->next=curr->next;
curr->next=new;
curr=curr->next;
}
}
void addRear(struct Node** headPtr, int v_new){
struct Node* new = malloc(sizeof(struct Node));
new->v=v_new;
new->next=NULL;
if(*headPtr==NULL){
*headPtr=new;
}else{
struct Node* curr = *headPtr;
while(curr->next!=NULL){
curr=curr->next;
}
curr->next=new;
}
}
void print(struct Node* head){
struct Node* curr = head;
while(curr!=NULL){
printf("%d ",curr->v);
curr = curr->next;
}
}
But when I run the following in main, I don't get any result. Here is my main code:
struct Node* head=NULL;
addRear(&head,1);
addRear(&head,2);
addRear(&head,5);
addRear(&head,7);
print(head);
printf("\n");
insert(&head);
print(head);
Two issues:
You are only creating one new node. Move the creation of the new node inside the loop.
curr=curr->next is not correct, because then curr will become equal to the new node. And so in the next iteration you will not have come any closer to the end of the list. The loop will never end. Instead you should do curr = new->next.
Here is the corrected code:
void insert(struct Node** headPtr){
struct Node* curr = *headPtr;
while (curr->next != NULL) {
struct Node* new = malloc(sizeof(struct Node)); // <---
new->v = curr->next->v - curr->v;
new->next = curr->next;
curr->next = new;
curr = new->next; // <---
}
}
For my Computer Science course we are needing to create 2 functions. One function needs to locate the serial position of the item being searched for (an int in this case) and the index of the previous item. The locateNode function (the function described above) needs to be used within the Remove function as well as other functions already written by the professor in the class. Remove is simply supposed to take the item before the one being removed and make it point to the item that was being pointed to by the removed item. Finally it will take the removed node and push it into an avail list within the same array (essentially there are 2 linked lists in the one array.) My functions are giving me the wrong output and I currently do not know which is wrong or if both functions are wrong.
void SortedList::Remove(ItemType anItem, bool& success)
// IN OUT
{
int previous, position;
success=locateNode(anItem, previous, position);
cerr<<success<<endl;
if (success)
{
int current=list[0].next;
list[previous].next=list[list[previous].next].next;
for (int i=1; i<position; i++)
{
current=list[i].next;
}
PushAvail(current);
}
} // end Remove
bool SortedList::locateNode(
ItemType anItem, int& previous, int& position) const
{
position=1;
previous=0;
int current=list[0].next;
bool isPresent = false;
for (int count=1; count <= size; count++)
{
if (list[current].item >= anItem)
{
if ( list[current].item == anItem)
{
cerr<<"Position "<< position<< endl;
cerr<<"Previous "<< previous<< endl;
isPresent = true;
}
return isPresent;
}
position++;
previous=list[previous].next;
current=list[current].next;
}
return isPresent;
}
i am very new in programming and its my 2nd semester in my college an dour teacher teach us about linked list and malloc function where we can make a node dynamically and increase or decrease its size . our teacher teach us how to store a integer value in list like this
struct node
{
int num;
struct node *next;
}head;
but i want to store a string say "name" of students in linked list instead of integer .. so i want to know how to do this ..
i write this code for that
#include <stdio.h>
#include <conio.h>
struct node
{
char name[20];
int age;
struct node *next;
};
//
void addatbegin(struct node **q,char name [20],int age)
{
struct node *r;
r=(struct node *)malloc(sizeof(struct node));
r->name=name;
r->age=age;
r->next=*q;
*q=r;
}
//
void addatend(struct node **q,char name[20],int age)
{
struct node *temp,*r;
if(*q==NULL)
{
temp=(struct node *)malloc(sizeof(struct node));
temp->name=name;
temp->age=age;
temp->next=NULL;
*q=temp;
}
else {
temp=*q;
while(temp->next!=NULL)
{
temp=temp->next;
}
r=(struct node *)malloc(sizeof(struct node));
r->name=name;
r->age=age;
r->next=NULL;
temp->next=r;
}}
void main()
{
struct node *head;
int age,ch;
char name[20];
head=NULL;
while(1)
{
printf("***** MENU ****** \n");
printf("1.Add at Begining of List\n");
printf("2.Add at End of List\n");
printf("3.Print the list\n");
printf("4.Exit\n \n");
printf("Enter Your choice:- ");
scanf(" %d",&ch);
switch(ch)
{
case1:printf("Enter Name:- ");
scanf(" %s",name);
printf("Enter Age:- ");
scanf(" %d",&age);
addatbegin(&head,name,age);
break;
}
getch(); }}
but its shwoing error lvalue missing
The function in resulting in an infinite loop. It is not able to return the number of nodes. Where am I going wrong?
int Count(struct node **head)
{
printf("entered");
struct node **temp;
int count = 0;
temp = &((*head)->next);
while ((&(*temp)->next) != head)
{
printf("entered");
temp = &((*temp)->next);
count++;
}
return count;
}
In the provide source code, the while-condition is referring to addresses of pointers (where the pointer is stored) and the struct node **head is pointing to a static location in the main() but (&(*temp)->next) is pointing to the allocated of the last item.
To compare items in a linked-list, you should compare pointers struct
node * instead of addresses of pointers struct node **.
In the Count() function, because the *head exists (not compared to
NULL), the counter count should start from 1 and to count all items in the circular-list, you should start by temp = &(*head); instead of the next item temp = &((*head)->next);.
Here after is a "Minimal, Complete, and Verifiable example".
#include <stdio.h>
#include <stdlib.h>
#define NODE_MAX (5)
struct node {
struct node *next;
};
int Count(struct node **head)
{
printf("entered");
struct node **temp;
int count = 1; // at least the '*head' node exists
temp = &(*head);// &((*head)->next);
while (((*temp)->next) != *head) // use '*head'
{
printf("entered");
temp = &((*temp)->next);
count++;
}
return count;
}
int main()
{
struct node array[NODE_MAX];
struct node *head, *temp;
head = &(array[0]);
temp = head;
for(int i=1;i<NODE_MAX;i++) {
temp->next = &(array[i]);
temp = temp->next;
}
temp->next = &(array[0]);
printf("\nCount = %d\n",Count(&head));
system("pause");
return (0);
}
It would be more simple to manage linked-list at pointers level like the following example:
int Count2(struct node **head)
{
printf("entered");
struct node *temp;
int count = 1;
temp = (*head); // pointers to the first
while (temp->next != *head) // direct pointer comparison
{
printf("entered");
temp = temp->next; // natural linked-list exploration
count++;
}
return count;
}