I've got a LinkedList node struct defined as such:
struct intnode {
int item;
struct intnode *next;
};
typedef struct intnode IntNode;
Which I am using to do some simple sorting. However, in creating this linked list, I am having difficulty with scope. In my main function I've got a Null header IntNode object to serve as the first element in the list, however I can't modify it within my insert function, despite the fact that I'm passing a pointer to it. The code never reaches the print statement saying the list is no longer empty, which I am confused by. Does this have something to do with defining a new IntNode element to add within the insert function which is then thrown away after the function is done?
int main() {
IntNode *header = NULL;
printf("Enter some numbers, ending with -1: ");
int a;
while(a != -1) {
scanf("%d",&a);
if(a != -1) {
insert(header, a);
}
}
return 0;
}
IntNode *createNode(int val) {
IntNode *new_node;
new_node = malloc(sizeof(IntNode));
new_node->item = val;
return new_node;
}
void insert(IntNode *header, int val) {
IntNode *newNode = createNode(val);
if(header == NULL) { //list is empty, so insert at front
printf("list still empty\n");
newNode->next = header;
header = newNode;
printf("%d",header->item);
} else {
printf("the list is no longer empty...");
//do more stuff here
}
}
If you want to modify a pointer, you need to pass a pointer of that pointer. Therefore
insert(header, a);
should be
insert (&header, a);
and adjust your insert() function accordingly.
Related
So I try to print a linked list, and it says that the argument head is incompatible argument type.
The list is already made correctly and works if not put in another function. I just can't understand why this specific function doesn't work.
struct data {
char foodName[FILENAME_MAX];
int rating;
float price;
};
typedef struct listElement {
struct listElement *next;
struct data food;
struct listElement *previous;
} listElement;
void printList(listElement *head);
void printElement(listElement *element);
int main()
{
struct data food;
listElement head;
printList(head); <-- this one gets an error
return 0;
}
void printList(listElement *head)
{
if (head == NULL) {
printf("Linked list is empty.\n");
} else {
printf("Printing linked list to result file...\n");
printElement(head);
printf("Linked list successfully printed to result file.\n");
}
}
void printElement(listElement *element)
{
if (element == NULL || file == NULL) {
return;
} else {
printf ("name = %s rating = %d price = %f\n", element->food.foodName, element->food.rating, element->food.price);
printElement(element->next);
}
In this function void printList(listElement *head) you are expecting a pointer to a listElement but in the main function you are calling the printList function with a listElement type, not a listElement* type.
To fix this you have to declare your head variable like this listElement* head; or you have to give the printList function a pointer to the head variable, like this printList(&head);.
Either way, it depends on what you want to do with it. But the first suggestion is more common.
I want to insert several nodes into an empty singly-linked list. It's OK when I insert the first node. However, the fist node is replaced by the second node when I call the function
the first time using function ListInsert(), the variable newNode is at the memory unit 0x7fffffffdf50. And the second time calling function ListInsert(), *L = 0x7fffffffdf50, **L = {m_Data = first node data, m_nextNode = NULL}. but when I create the newNode, it is still at the memory unit 0x7fffffffdf50. If I set newNode = second node data, it actually replace the first node but not insert into the linked list
struct t_Node
{
struct t_Data m_Data;
struct t_Node *m_nextNode;
}
typedef struct Node* t_LinkedList;
void ListInsert(t_LinkedList* L, int position, struct t_Data newData)
{
if (!*L)
{
struct t_Node newNode;
newNode.m_Data = newData;
newNode.m_nextNode = NULL;
(*L) = &newNode;
}
/* first Node is not NULL */
else
{
t_LinkedList anIterator;
anIterator = (*L);
if (!(*anIterator).m_nextNode)
{
struct t_Node newNode;
newNode.m_Data = newData;
newNode.m_nextNode = NULL;
(*anIterator).m_nextNode = &newNode;
}
}
}
t_LinkedList aLinkedList;
aLinkedList = NULL;
ListInsert(&aLinkedList,1,data1);
ListInsert(&aLinkedList,2,data2);
I expect to insert the second node based on the singly linked list with one node but not to replace the first node, and to maintain the structure of the program.
When you create new variable inside a function, the memory for that variable is allocated on the stack, that is why when the function returns the memory is no longer accessible. So we need to dynamically allocate memory in the heap. Read this to get a better idea about heap and stack. Here is the modified version of your code using dynamic allocation. Also note that when allocating memory dynamically, we need to free the memory when we are done using it, therefore I added a deleteList() function to delete the list.
#include<stdio.h>
#include<stdlib.h>
struct t_Node
{
int m_Data;
struct t_Node *m_nextNode;
};
typedef struct t_Node* t_LinkedList;
void ListInsert(t_LinkedList* L, int position, int newData)
{
struct t_Node * newNode = malloc(sizeof(struct t_Node));
newNode -> m_Data = newData;
newNode -> m_nextNode = NULL;
if (!*L)
{
(*L) = newNode;
}
/* first Node is not NULL */
else
{
t_LinkedList anIterator;
anIterator = (*L);
if (!(*anIterator).m_nextNode)
{
(*anIterator).m_nextNode = newNode;
}
}
}
void printList(t_LinkedList list)
{
while(list != NULL)
{
printf("%d\n", list->m_Data);
list = list -> m_nextNode;
}
}
void deleteList(t_LinkedList list)
{
t_LinkedList node = list -> m_nextNode;
while(node)
{
free(list);
list = node;
node = node -> m_nextNode;
}
}
int main()
{
t_LinkedList aLinkedList;
aLinkedList = NULL;
ListInsert(&aLinkedList,1,10);
ListInsert(&aLinkedList,2,20);
printList(aLinkedList);
deleteList(aLinkedList);
return 0;
}
I was having some confusion between ListNode and LinkedList. Basically my question was divided into 2 parts. For first part, I was supposed to do with ListNode. The function prototype as such:
int removeNode(ListNode **ptrHead, int index);
All function were working fine for the ListNode part. Then as for the second part, I was supposed to change the function above to this:
int removeNode(LinkedList *11, int index);
My code for part 1 which is working fine look like this:
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;
}
ListNode *findNode(ListNode *head, int index) {
ListNode *cur = head;
if (head == NULL || index < 0)
return NULL;
while (index > 0) {
cur = cur->next;
if (cur == NULL) return NULL;
index--;
}
return cur;
}
And here is my entire code for the part 2 which is not working:
#include "stdafx.h"
#include <stdlib.h>
typedef struct _listnode {
int num;
struct _listnode *next;
}ListNode;
typedef struct _linkedlist {
ListNode *head;
int size;
}LinkedList;
void printNode2(ListNode *head);
int removeNode2(LinkedList *ll, int index);
int main()
{
int value, index;
ListNode *head = NULL, *newNode = NULL;
LinkedList *ptr_ll = NULL;
printf("Enter value, -1 to quit: ");
scanf("%d", &value);
while (value != -1) {
if (head == NULL) {
head = malloc(sizeof(ListNode));
newNode = head;
}
else {
newNode->next = malloc(sizeof(ListNode));
newNode = newNode->next;
}
newNode->num = value;
newNode->next = NULL;
scanf("%d", &value);
}
printNode2(head);
printf("\nEnter index to remove: ");
scanf("%d", &index);
removeNode2(ptr_ll, index);
printNode2(head);
return 0;
}
void printNode2(ListNode *head) {
printf("Current list: ");
while (head != NULL) {
printf("%d ", head->num);
head = head->next;
}
}
int removeNode2(LinkedList *ll, int index) {
ListNode *head = ll->head;
if (head == index)
{
if (head->next == NULL)
{
printf("There is only one node. The list can't be made empty ");
return 1;
}
/* Copy the data of next node to head */
head->num = head->next->num;
// store address of next node
index = head->next;
// Remove the link of next node
head->next = head->next->next;
return 0;
}
// When not first node, follow the normal deletion process
// find the previous node
ListNode *prev = head;
while (prev->next != NULL && prev->next != index)
prev = prev->next;
// Check if node really exists in Linked List
if (prev->next == NULL)
{
printf("\n Given node is not present in Linked List");
return 1;
}
// Remove node from Linked List
prev->next = prev->next->next;
return 0;
}
When I try to run the part 2, the cmd just not responding and after a while, it just closed by itself and I have no idea which part went wrong. I was thinking am I in the correct track or the entire LinkedList part just wrong?
When I tried to run in debug mode, this error message popped up:
Exception thrown at 0x01201FD1 in tut.exe: 0xC0000005: Access violation reading location 0x00000000.
If there is a handler for this exception, the program may be safely continued.
Thanks in advance.
You say that you got the linked list to work wihen the list is defined via the head pointer only. In this set-up, you have to pass a pointer to the head pointer when the list may be updated, and just the head pointer when you only inspect the list without modifying, for example:
int removeNode(ListNode **ptrHead, int index);
ListNode *findNode(ListNode *head, int index);
Here, the head pointer is the handle for the list that is visible to the client code.
The approach with the list struct defines a new interface for the linked list. While the head node is enough, it might be desirable to keep track of the tail as well for easy appending or of the number of nodes. This data can be bundles in the linked list struct.
What that means is that the handling of the nodes is left to the list and the client code uses only the linked list struct, for example:
typedef struct ListNode ListNode;
typedef struct LinkedList LinkedList;
struct ListNode {
int num;
ListNode *next;
};
struct LinkedList {
ListNode *head;
ListNode *tail;
int size;
};
void ll_print(const LinkedList *ll);
void ll_prepend(LinkedList *ll, int num);
void ll_append(LinkedList *ll, int num);
void ll_remove_head(LinkedList *ll);
int main()
{
LinkedList ll = {NULL};
ll_append(&ll, 2);
ll_append(&ll, 5);
ll_append(&ll, 8);
ll_print(&ll);
ll_prepend(&ll, 1);
ll_prepend(&ll, 0);
ll_print(&ll);
ll_remove_head(&ll);
ll_print(&ll);
while (ll.head) ll_remove_head(&ll);
return 0;
}
There's also one difference: In the head-node set-up, the head node might be null. Here, the list cannot be null, it must exist. (Its head and tail members can be null, though.) Here the list is allocated on the stack, its address &ll must be passed to the functions.
In the linked list set-up, the distinction between modifying and read-only access is done via the const keyword:
void ll_print(const LinkedList *ll);
void ll_prepend(LinkedList *ll, int num);
In your example, you take a mixed approach with two independent structures, a head node and a list. That can't work, one single list is described by one struct, pick one.
The advantage to the linked list structure approach is that all required data like head, tail and size are always passed together to a function. You can also hide the implementation from the user by not disclosing the struct members, so that theb user can only work on pointers to that struct.
Finally, here's an example implementation of the above interface for you to play with:
void ll_print(const LinkedList *ll)
{
ListNode *node = ll->head;
while (node != NULL) {
printf("%d ", node->num);
node = node->next;
}
putchar('\n');
}
void ll_prepend(LinkedList *ll, int num)
{
ListNode *nnew = malloc(sizeof *nnew);
nnew->next = ll->head;
nnew->num = num;
ll->head = nnew;
if (ll->tail == NULL) ll->tail = ll->head;
ll->size++;
}
void ll_append(LinkedList *ll, int num)
{
ListNode *nnew = malloc(sizeof *nnew);
nnew->next = NULL;
nnew->num = num;
if (ll->tail == NULL) {
ll->tail = ll->head = nnew;
} else {
ll->tail->next = nnew;
ll->tail = nnew;
}
ll->size++;
}
void ll_remove_head(LinkedList *ll)
{
if (ll->head) {
ListNode *ndel = ll->head;
ll->head = ll->head->next;
ll->size--;
free(ndel);
}
}
I try to print a linked list but it didn't print all of the member in the list.can you explain what is the issue in my code? is code line (newhead=newhead->next) moves even the rest of the list is on the another function?
#include <stdio.h>
#include <stdlib.h>
struct test_struct{
int data;
struct test_struct *next;
};
struct test_struct* create();
void add_node();
int main()
{
add_node();
return 0;
}
void add_node()
{
struct test_struct* head = create();
struct test_struct* newhead;
newhead = malloc(sizeof(struct test_struct));
newhead->data=2;
newhead->next=head;
head=newhead;
while(newhead->next != NULL)
{
printf("%d\n",newhead->data);
newhead=newhead->next;
}
}
struct test_struct* create()
{
struct test_struct* head=NULL;
struct test_struct* temp = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL==temp)
{
printf("error in memory");
return 0;
}
temp->data=5;
temp->next=head;
head=temp;
return head;
}
Your while loop stops when it is on a node with no next node; it doesn't print the data on that node.
Instead, you want to stop when it is pointing to no node; that is, just after it's "fallen off the end" of your list:
while(newhead != NULL)
{
printf("%d\n",newhead->data);
newhead=newhead->next;
}
Line 26 should be while (newhead != NULL).
If you want to keep growing this, you could also review the purpose of each function, since add_node() and create() are doing almost the same thing, plus add_node() also prints the list, which could be the purpose of a separate function.
#include <stdio.h>
struct list
{
int data;
struct list *next;
};
struct list *start, *end;
void add(struct list *head, struct list *list, int data);
void delete(struct list *head, struct list *tail);
int main(void)
{
start=end=NULL;
add(start, end, NULL);
add(start, end, NULL);
printf("First element: %d");
delete(start, end);
return 0;
}
void add(struct list *head, struct list *tail, int data)
{
if(tail==NULL)
{
head=tail=malloc(sizeof(struct list));
head->data=data; head->next=NULL;
} else {
tail->next=malloc(sizeof(struct list));
tail=tail->next;
tail->data=data;
tail->next=NULL;
}
}
void delete(struct list *head, struct list *tail)
{
struct list *temp;
if(head==tail)
{
free(head);
head=tail=NULL;
} else {
temp=head->next;
free(head);
head=temp;
}
}
I am aiming to return an output of 3 but keep getting random results. Any insight is greatly appreciated
As you want to modify head and tail you need to pass a pointer to them.
i.e.
void add(struct list **head, struct list **tail, int data)
{
if(*tail==NULL)
{
*head = *tail = malloc(sizeof(struct list));
(*head)->data = data;
(*head)->next = NULL;
} else {
(*tail)->next = malloc(sizeof(struct list));
*tail = (*tail)->next;
(*tail)->data = data;
(*tail)->next = NULL;
}
}
Do similarly for the other function. Then head and tail will also change outside the function.
The line
printf("First element: %d");
It requires an integer to print - supply it - see the manual page for printf
Avoid using keywords for C++ in C programs - such as delete
Parameters of C functions are passed by value. Thus, the changes that you make to the values of head and tail in the add() function will not be reflected in main() from which add() is called.
And, it doesn't seem that you've supplied a second parameter for printf(), so the %d format is not going to get the integer value that it will be looking for.
In your program start and end are global variables, so there is no need to pass it as arguments to other functions, because other methods can directly access it.
//Structure to store data
struct list
{
int data;
struct list *next;
};
// global variables
struct list *start, *end;
void add(int);
void delete();
// start of program
int main(void)
{
start=end=NULL;
add(5);
add(6);
printf("\nFirst element: %d",start->data);
delete();
printf("\nFirst element: %d",start->data);
return 0;
}
//add node to list
void add(int data)
{
if(end==NULL)
{
start=end=malloc(sizeof(struct list));
start->data=data; start->next=NULL;
} else {
end->next=malloc(sizeof(struct list));
end=end->next;
end->data=data;
end->next=NULL;
}
}
// delete node from list
void delete()
{
struct list *temp;
if(start==end)
{
free(start);
start=end=NULL;
} else {
temp=start->next;
free(start);
start=temp;
}
}
OUTPUT:
First element: 5
First element: 6
Note:
If you don't want your start and end to be global than it can be a local variable of main function. Here you have to either work on double pointer mechanism or return memory address to retain the modification.
There are a number of problems here.
First, when you pass a pointer to a function, the pointer is passed by value. Any changes to the pointer in the called function will not be reflected in the calling function. To change what the pointer in the calling function is pointing to, you need to pass a pointer-to-pointer. So your add()function needs to be:
void add(struct list **head, struct list **tail, int data) {
if(*tail == NULL) {
*head = *tail = malloc(sizeof(struct list));
(*head)->data = data;
(*head)->next = NULL;
}
else {
(*tail)->next = malloc(sizeof(struct list));
(*tail) = (*tail)->next;
(*tail)->data = data;
(*tail)->next = NULL;
}
return;
}
And your delete() function needs to be changed similarly.
Secondly, you are passing NULL as your data value to the add function. NULL is a pointer; it is typically defined as a macro, and could be (void*) 0 in the implementation. It should not be used as an integer. Pass 0 as the integer, not NULL.
Third, you have this statement:
printf("First element: %d");
Your format string has the conversion specifier %d but there is no argument that matches the %d. This is undefined behavior. What integer exactly are you trying to print?
Where do you expect the output 3, and for what reason?