Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 months ago.
Improve this question
When I run the program below - the output I get is
head node created
node addded with value of 22
node addded with value of 22343
node addded with value of 7
22
22343
7
last node has been removed
current last nodes value is 22343
22
22343
7
This issue is that , if the last node in the list is stated to have a data value of 22343 when the removenode function is called , how is it possble that the last value printed is 7 and not 22343 - when the traverse function is called? despite the fact that the *next pointer of the last node is set to NULL in the removenode funtion.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node_n
{
int value;
struct node *next;
};
typedef struct node_n node;
node* makeheadnode()
{
node *temp = (node*)malloc(sizeof(node));
temp->next = NULL;
temp->value = NULL;
printf("\n head node created");
return temp;
}
void addnode(node *target, int data)
{
while (target->next != NULL)
{
target = target->next;
}
target->next = (node*)malloc(sizeof(node));
target = target->next;
target->value = data;
target->next = NULL;
printf("\n node addded with value of %d ",target->value);
}
int removenode(node *target)
{
node *temp;
if(target->next == NULL)
{
printf("\n only one node is present");
return 1;
}
while(target -> next != NULL)
{
temp = target -> next;
if(temp -> next == NULL)
{
target->next == NULL;
printf("\n last node has been removed \n current last nodes value is %d",target->value);
return 1;
}
else
{
target = target-> next;
}
}
}
int traverse(node *target)
{
if(target->next == NULL)
{
printf("\n this list is empty");
return 1;
}
while (target->next != NULL)
{
target = target -> next;
printf("\n %d", target -> value);
}
return 1;
}
int main()
{
node *head = makeheadnode();
addnode(head,22);
addnode(head,22343);
addnode(head,007);
traverse(head);
removenode(head);
traverse(head);
}
The problem is a typo. In your removenode function, you have:
target->next == NULL;
Where it should be:
target->next = NULL;
If you compile with warnings on, i.e. -Wall or even -Werror, the compiler should have warned you with a message like equality comparison result unused.
Furthermore, since you're removing the node, you should free it so you don't have any memory leaks. Setting a pointer to NULL does not free the pointer. Many, including myself, also see it as good practice to set the pointer to NULL after freeing.
free(target->next)
target->next = NULL
For more info on that, see this post
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
First, I define a structure to implement linked list:
typedef struct node
{
int data;
struct node *next;
} Node;
Then, I have to insert an element into the linked list. And I cannot finish this part.
A example from my lecture notes tells me, when we insert an element, we should do something like that:
Node a, c; // originally
Node b; // insert-element
b->next = &c;
a->next = &b;
However, I have to declare a Node to implement it. But, here is my situation: I don't know the input size, maybe I have to insert 60 elements, or maybe I just have to insert 2 elements. What is the solution?
And another small, stupid problem, is there it any different between a->next and a.next?
This is how you can implement an empty linked-list:
typedef struct node
{
int data;
struct node *next;
} Node;
int main(){
Node *a, *b;
a=malloc(sizeof(Node));
//here check if allocation has been done, if not error
a->data=1;
a->next=NULL;
b=malloc(sizeof(Node));
b->data=2;
b->next=a;
//and so on
return 0;
}
in this way your linked-list will be like:
b ----> a -----> NULL
Now let's suppose you want to add 3 to the end of the linked-list; you can use this function:
void insertToEnd(Node *head, int newNumber)
{
Node *newNode, *tmp;
newNode=malloc(sizeof(Node));
newNode->data=newNumber;
newNode->next=NULL;
tmp=head;
if(head->next == NULL){
head->next = newNode;
}
else
{
while(tmp->next != NULL)
{
if(tmp->next == NULL)
{
tmp->next = newNode;
}
tmp = tmp->next;
}
}
head=tmp;
}
I hope it works fine because i don't have c compiler right now. check it and let me know that if the function works fine
The sensible thing is to create a function that prepends a new list node to an existing list. We use NULL to mean "the empty list". We prepend since that saves having to step through the entire list every time.
Node * list_prepend(Node *head, int data)
{
Node *n = malloc(sizeof *n);
if(n != NULL)
{
n->next = head;
n->data = data;
return n; /* The new head. */
}
return head;
}
Then use it like so:
int main(void)
{
Node *list;
list = list_prepend(NULL, 47);
list = list_prepend(list, 11);
}
If you don't know how many Nodes you'll get, you'll have to allocate memory at runtime. malloc() and free() will do the job.
The difference between a->next and a.next is, well actually, a.
In the first construction the "a" is a pointer to a struct, in the second case "a" is a struct itself.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
I'm loading in a file:
05 11 2014 14 53 00
AB01 52.408 -4.217
XY23 51.750 -4.300
PQ29 52.100 -6.000
NY23 52.000 -5.900
The first line gets put into a dateTime struct. My code is then supposed to loop through the rest of the lines, putting them into a linked list of structs. However, it creates a linked list of the same element in an infinite loop.
typedef struct observer{
char id[21];
float lat;
float longitude;
struct observer *next;
} observer;
printf("Please enter the name of the observer file: ");
scanf("%s", fileName);
FILE* f1 = fopen(fileName, "r");
if(f1 == NULL)
{
perror("Error opening file");
return;
}
fscanf(f1, "%d %d %d %d %d %d", &dateTime.date, &dateTime.month,
&dateTime.year, &dateTime.hour, &dateTime.minute, &dateTime.second);
while(fscanf(f1, "%s %f %f", temp_id, &temp_lat, &temp_long))
{
struct observer *new_obs = make_observer(temp_id, temp_lat, temp_long);
insert_observer(new_obs, &observer_start);
print_observer(&observer_start);
}
fclose(f1);
observer* make_observer(char *id, float lat, float longitude)
{
observer *node = (observer*) malloc(sizeof(observer));
strcpy(node->id, id);
node->lat = lat;
node->longitude = longitude;
node->next = NULL;
return node;
}
void insert_observer(observer *node, observer **list)
{
observer *current;
observer *previous = NULL;
//int inserted = 0;
if(*list == 0)
{
*list = node;
return;
}
current = *list;
while(current != NULL)
{
if(previous != NULL)
{
previous->next = node;
}
else
{
*list = node;
}
previous = current;
current = current->next;
}
}
Try changing your insert function to this:
void insert_observer(observer *node, observer **list)
{
if (*list)
{
observer *current = *list;
observer *previous;
while (current)
{
previous = current;
current = current->next;
}
previous->next = node;
}
else
*list = node;
}
This just finds the end of the list and attaches the node to the last list item.
You also need to change the main loop while condition to check that the expected number of fields have been read:
while (fscanf(f1, "%s %f %f", temp_id, &temp_lat, &temp_long) == 3)
I need to create the push method for a program that push an element into a stack. I have created this typedef:
typedef struct node{
int value;
struct node *next;
} Node;
With this snippet of code in my main:
Node *stackptr;
stackptr = NULL;
This is where I have a problem and am not sure exactly what is going on - In my push method im not sure if I am returning the updated pointer to the top of the stack. Im suppose to check if it is empty as well but I am going to get to that last. Here is the push() function:
void push(Node *stkptr, int i){
Node *temp;
temp = malloc(sizeof(Node));
temp->value = i;
temp->next = *stkptr;
return *stkptr = temp;
}
Hope this makes some sort of sense what I am trying to get across. Thanks for any advice you are able to give me. Hope all is well.
Last I am in need of fixing my int pop() function! I have to return the value of the node that was popped. I believe I am almost there - my compiler is still throwing errors. This is what I have so far:
int pop(Node** stkptr){
Node *temp;
temp = malloc(sizeof(Node));
if((*stkptr) == NULL){
fprintf(stderr, "The stack is empty. Pop is not allowed\n");
return 0;
}
else{
temp = *stkptr;
stkptr = *temp;
}
return stkptr;
free(temp);
}
However, the compiler is throwing the error:
incompatible types when assigning to type ‘struct Node **’ from type ‘Node’
warning: return makes integer from pointer without a cast
Can someone please help me fix my problem! Thanks!
There must be a lot of duplicates for this (for example, Implementing stack with linked list in C from the related questions section), but basically, you need to pass a pointer to a pointer into the function:
void push(Node **stkptr, int i)
{
Node *temp;
temp = malloc(sizeof(Node));
temp->value = i;
temp->next = *stkptr;
*stkptr = temp;
}
You also can't return a value from a function that returns void. You should also check that the memory allocation worked.
You'd call this from, for example, your main program:
Node *stack = NULL;
int i;
while (get_an_integer(&i) != EOF)
push(&stack, i);
where get_an_integer() is a hypothetical function that reads an integer from somewhere and assigns it to i, while returning a status (0 — got an integer; EOF — didn't get an integer).
An alternative design returns the new head of the stack from the function:
Node *push(Node *stkptr, int i)
{
Node *node;
node = malloc(sizeof(Node));
node->value = i;
node->next = stkptr;
return node;
}
with calling sequence:
Node *stack = NULL;
int i;
while (get_an_integer(&i) != EOF)
stack = push(stack, i);
A question about pop()
The pop() function appears to remove and destroy the first item on the stack, rather than returning it. However, there are a number of flaws in it, such as it allocates space, then overwrites the pointer with information from the stack, then returns before freeing the data. So, assuming that the demolition job is required, the code should be:
int pop(Node **stkptr)
{
assert(stkptr != 0);
Node *temp = *stkptr;
if (temp == NULL)
{
fprintf(stderr, "The stack is empty. Pop is not allowed\n");
return 0;
}
else
{
*stkptr = temp->next;
free(temp); // Or call the function to deallocate a Node
return 1;
}
}
This now returns 1 when successful and 0 when the stack was empty. Alternatively, if you wanted the value from the top of the stack returned rather than freed, then:
Node *pop(Node **stkptr)
{
assert(stkptr != 0);
Node *temp = *stkptr;
if (temp == NULL)
{
fprintf(stderr, "The stack is empty. Pop is not allowed\n");
return 0;
}
else
{
*stkptr = temp->next;
return temp;
}
}
Or, since you are told by the return value whether there was anything to pop, and printing in a library function can be objectionable, maybe even:
Node *pop(Node **stkptr)
{
assert(stkptr != 0);
Node *temp = *stkptr;
if (temp != NULL)
*stkptr = temp->next;
return temp;
}
Warning: none of the code has been submitted to a compiler for verification.
Bellow is the relevant code:
typedef struct Node_t {
ListElement data;
struct Node_t* next;
} Node;
struct List_t {
Node* head;
Node* tail;
Node* current;
int size;
CopyListElement copyF;
FreeListElement freeF;
};
static ListResult initializeNode(List list, ListElement element, Node* newNode){
printf("\nEntered initializeNode\n");
if ((list == NULL) || (element == NULL)) return LIST_NULL_ARGUMENT;
newNode = malloc(sizeof(Node));
if (newNode == NULL) return LIST_OUT_OF_MEMORY;
printf("\nWithin initializeNode, before copyF\n");
ListElement newElement = list->copyF(element);
printf("\nWithin initializeNode, after copyF\n");
if (newElement == NULL) return LIST_OUT_OF_MEMORY;
newNode->data = newElement;
printf("\nLast line within initializeNode\n");
return LIST_SUCCESS;
}
List listCreate(CopyListElement copyElement, FreeListElement freeElement){
//Check if there is a NULL argument.
if ((copyElement == NULL) || (freeElement == NULL)) return NULL;
//Check wether there is enough memory.
List newList = malloc(sizeof(List));
if (newList == NULL) return NULL;
//Initialize an empty List.
newList->head = NULL;
newList->tail = NULL;
newList->size = 0;
newList->current = NULL;
newList->copyF = copyElement;
newList->freeF = freeElement;
return newList;
}
ListResult listInsertFirst(List list, ListElement element){
printf("\nEntered listInsertFirst\n");
Node* newNode;
ListResult result = initializeNode(list, element, newNode);
printf("\n Node was initialized\n");
if (result != LIST_SUCCESS) {
return result;
}
printf("\nEntering logistic works within listInsertFirst\n");
//Finish logistic work within the Node.
newNode->next = list->head;
list->head = newNode;
list->size++;
printf("\nElement was inserted successfully\n");
printf("\nCheck list->CopyF within listInsertFirst\n");
list->copyF(element);
printf("\nCheck list->CopyF within listInsertFirst: PASSED\n");
return LIST_SUCCESS;
}
Within main function I'm trying:
List list = listCreate(©Int, &freeInt);
ListResult result;
int el=2;
//ListElement e1;
//ListElement e2;
result = listInsertFirst(list,&el);
printf("\nresult = %d\n", result);
result = listInsertFirst(list,&el);
printf("\nresult = %d\n", result);
After compiling and running I get:
Entered listInsertFirst
Entered initializeNode
Within initializeNode, before copyF
Within initializeNode, after copyF
Last line within initializeNode
Node was initialized
Entering logistic works within listInsertFirst
Element was inserted successfully
Check list->CopyF within listInsertFirst Segmentation fault: 11
For some reason the pointer [to function] list->copyF gets corrupted [I think].
I'm assuming this is C code, not C++, based on the tags. Given that you have a mix of data definitions and actual code statements, which I wouldn't expect to work in C, I'm not 100% sure it is real C, in which case I may be wrong about the error below.
First of all, the interface to initializeNode() doesn't do what you probably intend. You probably want:
static ListResult initializeNode(List list, ListElement element, Node** newNodep)
{
Node *newNode = malloc(sizeof(Node));
if (newNode == NULL) return LIST_OUT_OF_MEMORY;
ListElement newElement = list->copyF(element);
if (newElement == NULL) return LIST_OUT_OF_MEMORY;
newNode->data = newElement;
*newNodep = newNode;
return LIST_SUCCESS;
}
That way the Node you create gets passed back.
I don't know what CopyInt() does, but if it's really the function hitting the Bus Error the bug with initializeNode() can't be your problem. However, it's possible that you aren't seeing the output of all your printfs before the crash gets reported.
If CopyInt() does what I'd expect, it does something like:
ListElement CopyInt(int *val)
{
ListElement *e = malloc(sizeof(ListElement));
if (e)
e->val = *val;
return e;
}
The only way you are going to get a second-time bus error here is if you've messed up the data structures maintained by the library function malloc(). Unfortunately for that theory, I don't see anything worse than a memory leak here.
My guess that the bug that actually causes the crash is this line:
newNode->next = list->head;
Like #Arlie Stephens said - code for initializeNode doesn't do anything as the pointer is passed by value and the actual pointer still points to junk. So when you do newNode->next = list->head; you're basically writing to an unknown address and it's very likely to get a segmentation fault.
Why does it only happens on the second call? No idea, it's undefined behavior.
Crazy idea - it's possible that newNode->next is initialized to the address of copyF and trying to write into it cause you to corrupt copyF...Try printing the address of newNode->next and the address of copyF.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
thanx k-ballo, u solved my prevoius problem but then i landed into another one!!
i created nodes and then tried to display them, but every time i called append_node(), the double pointer **head_ptr(used to hold the address of the very first pointer *head, which in turn, holds the address of the very first node of the linked list), was holding a NULL value as if previous calls to append_node(&head, value) didnt add any node to *head.
so whenever i display the list, it reamins empty!! :
#include <stdio.h>
struct __node
{ int data;
struct __node *next;
};
typedef struct __node node;
int append_node(node **head_ptr, int value) //double pointer head_ptr to simulate call-by-reference
{ node *temp, *q;
temp = (node *) malloc(sizeof(node));
if(!temp)
{ printf("\ninsufficient memory!!");
return -1;
}
q = *head_ptr; //as *head_ptr is address of a pointer (which is *head), so any changes made after this line in q should also be reflected in main().. (i guess so!)
temp->data = value;
temp->next = NULL;
if(q == NULL)
{ q = temp;
printf("\nq is empty");
return 0;
}
while( q->next != NULL)
{ q = q->next;
}
printf("\nq is not empty");
q->next = temp;
return 0;
}
int disp_list(node **head_ptr)
{ node *q;
int i=1;
q = *head_ptr;
if(q != NULL)
{ while( q != NULL )
{ printf("|%d-%d|--->", i++, q->data);
q = q->next;
}
}
else
{ printf("\nlist is empty!!");
}
return 0;
}
int main()
{ node *head=NULL;
int value, res, i=0;
while(i<3)
{ printf("\nenter the data to be inserted into the node: ");
scanf("%d", &value);
res = append_node( &head, value);
i++;
}
printf("\nprinting all the nodes...\n") ;
res = disp_list(&head);
printf("\n---------------\nexiting...\n\n\n");
return 0;
}
i know i could have returned *q from append_node() and reassigned it to *head or declared *head as global.. but i want to *head to be manipulated by so-called-pass-by-reference method only. (theres no pass-by-reference actually in c!) my compiler is: gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)
plz help..i m not an expert so please use easier terminology!! :p
Your initial call to append_node is passing a pointer to a pointer to node which is uninitialized (let's pressume its null, though it will probably be just garbage). Then you do
q = *head_ptr;
//above statement causes a segment fault error..
// that statement should be fine, we will get the value of main's head, which we pressume to be null
// now we will try to dereference null by accesing its next element
while( q->next != NULL)
{ q = q->next;
}
There are two major problems with this program:
head is not initialized and contains garbage.
You don't handle the case of an empty list in append_node().
Both problems will lead to segmentation fault errors.