I'm working on a C code. I have a singly linked list, and i want to delete a node,which i don't know the position of it. My struct is this:
struct list_node{
int num;
char name[25];
int year;
float money;
struct list_node *next;
};
typedef struct list_node node;
node *head=NULL;
I have a value which i have to compare with the node->name so it deletes the node. How can i do this? I had tried with this code to do this:
value=argv[2];
temp=head;
if(temp==NULL){
return 0;
}
if(strcmp(current->name,value)==0){
temp=head;
head=head->next;
free(temp);
return 0;
}
p=head;
while(p->next!=NULL){
if(strcmp(p->next->name,value)==0){
temp=p->next;
p->next=temp->next;
free(temp);
return 0;
}
p=p->next;
}
return 0;
}
but the node was not deleted. (I have a function to print the list)
Try this code.. I think you probably have made mistake in taking pointers to structures!
{
node* temp;
node * ptr=head;
if(ptr=NULL)
{
return 0;
}
else if(strcmp(ptr->name, name2)==0)
{
head=head->next;
free(ptr);
return 0;
}
while(ptr->next!=NULL)
{
if(strcmp(ptr->next->name, name2)==0)
{
temp=ptr->next;
ptr->next=ptr->next->next;
free(temp);
return 0;
}
ptr=ptr->next;
}
printf("Node not found!");
return 0;
}
I have a value which i have to compare with the node->name so it
deletes the node. How can i do this?
… not too complicated:
node *curr, **prev;
for (prev = &head; curr = *prev; prev = &curr->next)
if (strcmp(curr->name, value) == 0)
{
*prev = curr->next,
free(curr);
break;
}
Related
So I'm very new to programming, so I would like you to keep in mind theres a high chance I've made a very dumb or basic mistake. I have run into this problem while trying to create a linked list in C. For the output, I'm able to enter 2 elements before I get a segmentation fault:11.
#include<stdio.h>
struct node {
int data;
struct node *next;
};
void create(){
int temp1,temp2;
printf("Enter the number of elements\n");
scanf("%d",&temp1);
struct node *x=(struct node*)malloc(temp1*sizeof(struct node*));
for(int i=0;i<temp1;i++){
printf("loop\n");
printf("Enter a value\n");
scanf("%d",&temp2);
x->data=temp2;
printf("text\n");
x=x->next;
}
x->next=NULL;
}
int main(){
create();
}
x=x->next;
}
x->next=NULL;
you have not allocated any memory for the next and then you dereference it.
BTW you do not save anywhere the fist node so after the function call the list and allocated memory is lost
Hi I modified your code a bit. Below is the modified version
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
void print(struct node *head) {
while(head){
printf("%d->", head->data);
head = head->next;
}
printf("\n");
}
void free_mem(struct node *head) {
struct node *temp;
while(head){
temp = head;
head = head->next;
free(temp);
}
}
//Insertion at the end
struct node *create(struct node *head){
int temp1,temp2;
struct node *temp_node;
printf("Enter the number of elements\n");
if(scanf("%d",&temp1) < 1){
printf("scanf for temp1 failed!\n");
exit(1);
}
for(int i=0;i<temp1;i++){
struct node *x;
if(! (x = (struct node*)malloc(sizeof(struct node)))){
printf("malloc of new node failed!\n");
exit(1);
}
printf("Enter a value\n");
if(scanf("%d",&temp2) < 1){
printf("scanf for temp2 failed!\n");
exit(1);
}
x->data=temp2;
x->next = NULL;
if(!head){
head = x;
head->next = NULL;
continue;
}
//Moving to end
temp_node = head;
while(temp_node->next){
temp_node = temp_node->next;
}
temp_node->next = x;
}
return head;
}
int main() {
struct node *head = NULL;
head = create(head);
print(head);
//freeing dynamically allocated memory
free_mem(head);
return 0;
}
Please revert for any clarifications.
Task is to create a linked list consisting of objects. User inputs data for each individual Node in the main and then the object is being passed to push, which creates the list.
The problem comes in the printList function, where the condition for a break is never met.
For some reason the line head = head->next doesn't do anything, as the address of next with every iteration remains the same.
typedef struct Node {
int a;
char asd[30];
struct Node *next;
}Node;
Node *head = NULL;
void push(Node**head, struct Node* object);
void printList(Node *head);
int main() {
struct Node {
int oA;
char oAsd[30];
struct Node *next;
};
struct Node *object = malloc(sizeof(struct Node));
int c = 0;
while (1) {
printf("This int will be stored in Node %d.\n", ++c);
scanf("%d", &object->oA);
getchar();
if (!object->oA) {
break;
}
printf("This string will be stored in Node %d.\n", c);
gets_s(object->oAsd, 30);
if (!(strcmp(object->oAsd, "\0"))) {
break;
}
push(&head, object);
}
printList(head);
return 0;
}
void push(Node ** head, struct Node* object)
{
Node *tmp = malloc(sizeof(Node));
tmp = object;
tmp->next = (*head);
(*head) = tmp;
}
void printList(Node *head) {
if (head == NULL) {
puts("No list exists.");
exit(9);
}
while (1) {
printf("-------------------------------\n");
printf("|Int: <%d> |||| String: <%s>.|\n", head->a, head->asd);
printf("-------------------------------\n");
if (head->next) {
printf("\n\n%p\n\n", head->next);
head = head->next;
}
else {
break;
}
}
}`
There are two major problems in your code:
You define struct Node both outside main and inside main
Here tmp = object; you copy the value of a pointer to another pointer but you really want to copy the value of a struct to another struct, i.e. *tmp = *object;.
Besides that - don't put head as a global variable.
So the code should be more like:
typedef struct Node {
int a;
char asd[30];
struct Node *next;
}Node;
void push(Node**head, struct Node* object);
void printList(Node *head);
int main() {
Node *head = NULL;
struct Node *object = malloc(sizeof(struct Node));
int c = 0;
while (1) {
printf("This int will be stored in Node %d.\n", ++c);
scanf("%d", &object->a);
getchar();
if (!object->a) {
break;
}
printf("This string will be stored in Node %d.\n", c);
gets_s(object->asd, 30);
if (!(strcmp(object->asd, "\0"))) {
break;
}
push(&head, object);
}
printList(head);
return 0;
}
void push(Node ** head, struct Node* object)
{
Node *tmp = malloc(sizeof(Node));
*tmp = *object; // Copy the struct
tmp->next = (*head);
(*head) = tmp;
}
void printList(Node *head) {
if (head == NULL) {
puts("No list exists.");
exit(9);
}
while (1) {
printf("-------------------------------\n");
printf("|Int: <%d> |||| String: <%s>.|\n", head->a, head->asd);
printf("-------------------------------\n");
if (head->next) {
printf("\n\n%p\n\n", head->next);
head = head->next;
}
else {
break;
}
}
}
I'm writing a program that creates a doubly linked list and removes a certain element from it. Everything pretty much works, except for the part when the list consists only of 1 element and when I try to delete it, program crashes. Any suggestions?
#include <stdio.h>
#include <stdlib.h>
struct Node{
int data;
struct Node* next;
struct Node* prev;
};
struct Node* head;
struct Node* tail;
struct Node* CreateNewNode(int x){
struct Node* newNode=(struct Node*)malloc(sizeof(struct Node));
newNode->data=x;
newNode->next=NULL;
newNode->prev=NULL;
return newNode;
}
void InsertAtBegin(int x){
struct Node* newNode=CreateNewNode(x);
if(head == NULL) {
head = newNode;
tail = newNode;
return;
}
head->prev = newNode;
newNode->next = head;
head = newNode;
}
void InsertAtEnd(int x){
struct Node* newNode=CreateNewNode(x);
if(tail==NULL){
head=newNode;
tail=newNode;
return;
}
tail->next=newNode;
newNode->prev=tail;
tail=newNode;
}
struct Node* PointTo(int k){
struct Node* curr=head;
int i=1;
while(curr!=NULL && i<k){
curr=curr->next;
i++;
}
return curr;
}
void DelFromList(int k){
struct Node* temp;
temp=PointTo(k);
if(k==1){
head=temp->next;
temp->next->prev=NULL;
free(temp);
return;
}
if(temp->next==NULL){
temp->prev->next=NULL;
tail=temp->prev;
free(temp);
return;
}
if(temp->next==NULL && temp->prev==NULL){
head=NULL;
tail=NULL;
printf("atpazista\n");
free(temp);
return;
}
temp->next->prev=temp->prev;
temp->prev->next=temp->next;
free(temp);
}
void Print(){
struct Node* temp = head;
if(head==NULL){
printf("List empty\n");
return;
}
printf("List: ");
while(temp != NULL) {
printf("%d ",temp->data);
temp = temp->next;
}
printf("\n");
}
void Read(int *x){
while(scanf("%d", x)==0){
printf("NUMBERS ONLY\n");
scanf("%s");
}
}
void Free(){
struct Node* temp=head;
while(temp->next!=NULL){
temp=temp->next;
free(temp->prev);
}
}
int main()
{
int n=0, x;
printf("Number of elements?\n");
while(n<=0){
Read(&n);
}
int i;
for(i=0; i<n; i++){
printf("Type a number\n");
Read(&x);
InsertAtEnd(x);
}
Print();
printf("Head: %d\n", head->data);
printf("Tail: %d\n", tail->data);
printf("Number of element to be deleted?\n");
n=0;
while(n<=0){
Read(&n);
}
DelFromList(n);
Print();
printf("Head: %d\n", head->data);
printf("Tail: %d\n", tail->data);
Free();
return 0;
}
Perhaps swap the ordering of:
if(temp->next==NULL){
temp->prev->next=NULL;
tail=temp->prev;
free(temp);
return;
}
if(temp->next==NULL && temp->prev==NULL){
head=NULL;
tail=NULL;
printf("atpazista\n");
free(temp);
return;
}
The latter code will never execute because the first case already did, and returned
There's nothing wrong when i built the program in both VS & codeblock. While, when i ran it, it either broke after i typed in the index number or just show letters infinitely...
#include<stdio.h>
#include<stdlib.h>
// list_node structure
typedef struct list_node{
int item;
struct list_node *next;
}ListNode;
//call functions that will be used
void printNode(ListNode *head);
int removeNode(ListNode **ptrhead, int index);
ListNode *findNode(ListNode *head, int index);
int main(){
int index,value;
ListNode *head=NULL;
ListNode *temp;
//build the list
printf("Enter a value:");
scanf("%d",&value);
do{
temp->item=value;
if(head==NULL){
head=(struct list_node *)malloc(sizeof(ListNode));
temp=head;
}
else{
temp->next=(struct list_node *)malloc(sizeof(ListNode));
temp=temp->next;
}
printf("Enter a value:");
scanf("%d",&value);
}while(value!=-1);
printf("Enter the index: ");
scanf("%d",&index);
// remove the node at the position indexed
// when I used debugger, I saw it didn't execute this step. Maybe there's something wrong with it....
removeNode(&head,index);
printNode(head);
return 0;
}
void printNode(ListNode *head){
if (head==NULL)
exit(0);
while(head!=NULL){
printf("%d",head->item);
head=head->next;
}
printf("\n");
}
ListNode *findNode(ListNode *head,int index){
if(head==NULL||index<0)
return NULL;
while(index>0){
head=head->next;
index--;
}
return head;
}
int removeNode(ListNode **ptrhead,int index){
ListNode *pre,*cur,*temphead;
temphead=*ptrhead;
if(findNode(temphead,index)!=NULL){
pre=findNode(temphead,index);
cur=pre->next;
temphead->next=cur;
return 0;
}
else
return -1;
}
prev=NULL;
cur=head;
/* traverse the list until you find your target */
while (cur != NULL && cur->id != search_id) {
prev=cur;
cur=cur->next;
}
/* if a result is found */
if (cur != NULL) {
/* check for the head of the list */
if (prev == NULL)
head=cur->next;
else
prev->next=cur->next;
/* release the old memory structure */
free(cur);
}
Whats up dude....I hope u will get it... :)
temp->item=value; - you're dereferencing temp when it's uninitialized. Undefined behavior, crash and burn.
In your loop,
temp->item=value;
No space has been allocated to temp. Hence, this will crash !!
if(head==NULL){
head=(struct list_node *)malloc(sizeof(ListNode));
temp=head;
Typically, you woud allocate a temp node and assign it to head as head = temp. Another point which is missing is when a new node is created, the next should be initialized to NULL as temp->next = NULL
In removeNode,
if(findNode(temphead,index)!=NULL){
pre=findNode(temphead,index);
pre will be pointing to the node to be removed, but temphead will still be pointing to head of the list. findNode will not modify the temphead. So tmphead->next = cur will modify the head always
int removeNode(ListNode **ptrhead,int index){
ListNode *pre,*cur;
if (index==-1)
return 1;
else if(findNode((*ptrhead),(index))!=NULL){
pre=findNode((*ptrhead),(index-1));
cur=pre->next;
pre->next=cur->next;
return 0;
}
else
return 1;
}
I modified the last part and addedtemp->next=NULLin the main function. this program can ran well now!
I'm working on a singly linked list in C. This is what I've written so far.
C program
#include<stdio.h>
#include<stdlib.h>
struct Node{
int value;
struct Node *next;
};
struct Node* init()
{
struct Node* head=NULL;
head=malloc(sizeof(struct Node));
head->value=-1;
return head;
}
int length(struct Node* head)
{
struct Node* current=head;
int length=0;
while(current!=NULL)
{
length++;
current=current->next;
}
return length;
}
void print(struct Node* head)
{
int i=0;
int len=length(head);
for(i=0;i<len;i++)
{
printf("%d%d",i,head[i].value);
printf("\n");
}
}
struct Node* insert(int data,struct Node* head)
{
struct Node* current=NULL;
if(length(head) > 0)
{
int val=head->value;
if (val==-1)
{
head->value=data;
head->next=NULL;
}
else
{
current=malloc(sizeof(struct Node));
current->value=data;
current->next=head;
head=current;
}
}
else
{
printf("List is empty");
}
return head;
}
int main()
{
/* printf("Hello"); */
struct Node *head=init();
head=insert(20,head);
head=insert(30,head);
head=insert(40,head);
print(head);
printf("%d",length(head));
return 0;
}
The output values I get are:
Index Value
0 40
1 0
2 0
and for length is 3. I'm not able to grasp what I'm doing wrong here in pointer manipulation.
One obvious problem is not setting next to NULL on init - that would fail when checking length on the empty list
But your real problem is the print function
You can't use:
head[i].value
That notation is only valid for arrays, you need to use next to find each member
The Init function should set Next to NULL
struct Node* init()
{
struct Node* head=NULL;
head=malloc(sizeof(struct Node));
head->value=-1;
head->next=NULL;
return head;
}
otherwise the first call to length return an undefined result ( or GPF ).
Here:
for (i = 0; i < len; i++)
{
printf("%d%d", i, head[i].value);
printf("\n");
}
You need to advance from one node to another with head = head->next in the same manner as you do it in length(). head[i] won't do it.
It's unclear why your init() and insert() are so unnecessarily complicated and I don't even want to try to guess why. I want to suggest a better insert() and no init():
struct Node* insert(int data, struct Node* head)
{
struct Node* current;
current = malloc(sizeof(struct Node));
current->value = data;
current->next = head;
return current;
}
And then you do this:
int main(void)
{
struct Node *head = NULL;
head = insert(20, head);
head = insert(30, head);
head = insert(40, head);
print(head);
printf("%d", length(head));
return 0;
}
The notation head[i].value is only valid for arrays but not for linked lists. Arrays and linked lists are completely different, allocation of memory towards arrays is premeditated where as for linked lists it's dynamic. That is the reason why we use pointers for linked lists.
In init() you didn't assign null which causes the loop to run infinite times when you call length() for first time.
I am posting the modified code of print function:
void print(struct Node* head)
{
int i=0;
int len=0;
struct Node* current=head;
for(i=0;i<len;i++)
{
printf("%d %d",i,current->value);
print("\n");
current=current->next;
}
}