I am practicing creating a link list, but encountered a problem when trying to insert an item to the front of the list. The code in my insert function works properly if I put it within main, but not when run separately as a function.
I am using a pointer as a argument in the function so I don't understand why the value in my print statement isn't changing to 100 which should be at the front of the linked list using the insert function (When I run the function 61 is printed, I am aiming for 100 to be printed).
Thanks for the help!
#include <stdio.h>
#include <stdlib.h>
typedef struct node *nodePtr;
typedef struct node node;
struct node {
int value;
nodePtr next;
};
node insert(node *first, int value)
{
nodePtr temp;
temp = malloc(sizeof(node));
temp->value = value;
temp->next = first;
first = temp;
}
int main()
{
nodePtr first;
first = malloc(sizeof(node));
first->value = 61;
first->next = NULL;
insert(first, 100);
printf("%d", first->value);
}
your passing a pointer to the node as a argument to the function and changing the value of formal parameter does not change the value of the actual parameter do this it should work.
enter code here
#include <stdio.h>
#include <stdlib.h>
typedef struct node *nodePtr;
typedef struct node node;
struct node {
int value;
nodePtr next;
};
void insert(node **first, int value)
{
nodePtr temp;
temp = malloc(sizeof(node));
temp->value = value;
temp->next = *first;
*first = temp;
}
int main()
{
nodePtr first;
first = malloc(sizeof(node));
first->value = 61;
first->next = NULL;
insert(&first, 100);
printf("%d",first->value);
}
You have passed a pointer to function insert() and stored it in a variable first whose scope is local to function insert(). Now you have
updated pointer first in function insert().
When you will return to main() function updated value of pointer next is lost that is why you are getting unexpected result while printing value in main().
To summarise:
first = malloc(sizeof(node)); // let's say first is p1
...
insert(first, 100); // first is P1
....
node insert(node *first, int value) // first is p1
....
tmp = malloc(sizeof(node)); // let's say tmp is p2
first = temp; // Now first has become p2 but its scope is local to insert()
....
printf("%d", first->value); // first is still p1 here
Solution
node* insert(node *first, int value)
{
nodePtr temp;
temp = malloc(sizeof(node));
temp->value = value;
temp->next = first;
first = temp;
return first;
}
int main()
{
nodePtr first;
first = malloc(sizeof(node));
first->value = 61;
first->next = NULL;
first = insert(first, 100);
printf("%d", first->value);
return 0;
}
Related
This question already has answers here:
Linked lists - single or double pointer to the head
(3 answers)
What is the reason for using a double pointer when adding a node in a linked list?
(15 answers)
Closed 10 months ago.
#include<stdio.h>
#include<stdlib.h>
void insert_front(struct node* head, int block_number);
void insert_rear(struct node* head, int block_number);
void print_list(struct node* head);
struct node {
int block_number;
struct node* next;
};
int main(void)
{
struct node* list = NULL;
insert_front(list, 10);
insert_rear(list, 20);
insert_front(list, 30);
insert_rear(list, 40);
print_list(list);
return 0;
}
void insert_front(struct node* head, int block_number)
{
struct node* p = malloc(sizeof(struct node));
p->block_number = block_number;
p->next = head;
head = p;
return head;
}
void insert_rear(struct node* head, int block_number)
{
struct node* p = malloc(sizeof(struct node));
p->block_number = block_number;
p->next = NULL;
if (head == NULL) {
head = p;
}
else {
struct node* q = head;
while (q->next != NULL) {
q = q->next;
}
q->next = p;
}
}
void print_list(struct node* head)
{
struct node* p = head;
while (p != NULL) {
printf("--> %d ", p->block_number);
p = p->next;
}
printf("\n");
}
When I ran it, there was no result at all.
Now, in the insert_front function p->block_number = block_number, a message appears saying that the NULL pointer 'p' is being dereferenced... (The same thing appears in the insert_rear function.)
Could it be that I am declaring the pointer wrong?
Both insert_front and insert_rear need to convey possibly head modification back to the caller, and the caller needs to reap that information. Both should be declared to return struct node *, do so, and the code in main react accordingly. E.g.:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
struct node * insert_front(struct node *head, int block_number);
struct node * insert_rear(struct node *head, int block_number);
void print_list(struct node *head);
struct node
{
int block_number;
struct node *next;
};
int main(void)
{
struct node *list = NULL;
list = insert_front(list, 10);
list = insert_rear(list, 20);
list = insert_front(list, 30);
list = insert_rear(list, 40);
print_list(list);
return 0;
}
struct node *insert_front(struct node *head, int block_number)
{
struct node *p = malloc(sizeof(struct node));
p->block_number = block_number;
p->next = head;
head = p;
return head;
}
struct node *insert_rear(struct node *head, int block_number)
{
struct node *p = malloc(sizeof(struct node));
p->block_number = block_number;
p->next = NULL;
if (head == NULL)
{
head = p;
}
else
{
struct node *q = head;
while (q->next != NULL)
{
q = q->next;
}
q->next = p;
}
return head;
}
void print_list(struct node *head)
{
struct node *p = head;
while (p != NULL)
{
printf("--> %d ", p->block_number);
p = p->next;
}
printf("\n");
}
Output
--> 30 --> 10 --> 20 --> 40
I leave the memory leaks for you to resolve.
In C all variables are passed by value – if you pass a pointer, then it is copied, too (not the pointed to object, of course...), and function parameters, apart from being initialised from outside, are nothing more than local variables. Thus via head = p; you just assign the local copy of the outside pointer, not the latter itself!
To fix that you have two options:
Return the new head and make the user responsible for re-assigning the returned value to his own head pointer.
Accept the head as pointer to pointer.
With second approach a user cannot forget to re-assign the (potentially) new head, so that's what I'd go with:
void insert_whichEver(node** head, int block_number)
{
// use `*head` where you had `head` before...
}
void demo()
{
node* head = NULL;
insert_front(&head, 1012);
}
And in insert_front drop return head;, a function with void cannot return anything concrete and does not require a return at all (but bare return; can be used to exit a function prematurely).
I am new to C programming. I am trying to implement Linked list by myself. I am encountering problem with pointers
I have function
void Insert(Node* head, int x)
to insert node at the beginning of Linked list. The problem is that when I insert the very first node and Node *head is NULL, the function Insert is not able to change the pointer address of null pointer to the newly created node. It seems as if the Node *head is passed by value and not by reference.
Code is provided below. In order to debug how address is changed throughout the execution, I used printf function.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
int main() {
Node *head = (Node*) malloc(sizeof(Node));
head = NULL;
printf("head in main(): %d\n", head); // For example: 100
Insert(head, 25);
return 0;
}
void Insert(Node *head, int x) {
Node *temp = (Node*) malloc(sizeof(Node));
temp->data = x;
temp->next = head;
printf("temp->next address: %d\n", temp->next); // also 100
head = temp;
printf("%d\n", head); // not 100, something else i.e 200
}
It seems as if the Node *head is passed by value and not by reference.
That is exactly right -- in C every parameter is always passed by value. The pointer is a value, and that value is passed by value, and the call
Insert(head, 25);
can never change the value of the variable named head. It reads the value of the variable (this value is a null pointer), gives that value to the function and never touches the variable head again no matter what the function does.
(Note that in your program you have two variables that are both named head -- one in main() and the other in Insert(). The variable in Insert() silently disappears when the function returns; nothing will automatically try to copy its value to the similarly-named variable in main()).
If you want to (conceptually) pass head by reference, you need to actually pass a pointer to it -- that is, in this case, a pointer to a pointer! You'd need to declare your function as
void Insert(Node **head, int x) { ... }
and call it as
Insert(&head, 25);
Then the actual parameter is a pointer to the variable head which gives the function a chance to update that variable, if you deference the parameter where appropriate:
// ...
temp->next = *head;
// ...
*head = temp;
// ...
Pass a pointer to a pointer to head. That way, you can set head to null.
void Insert(Node **head, int x) {
...
if (*head == NULL) {
*head = temp;
}
else {
...
*head->next = temp;
}
}
Usage:
Node *head = NULL;
Insert(&head, 10);
Having three answers suggesting the same I would like to offer an alternative:
Instead of passing a Node ** to Insert() you could instead have it return the new head, thus:
Node *Insert( Node *head, int x )
{
... your code ...
return head;
}
and if you call it by
head = Insert( head, 24 );
That is neither better nor worse then the other solution so you my do whatever you prefer
There are number of issues here.
1. Your printf statements need to be corrected.
2. To insert function you can pass double pointer.
3. Inside main function, you need not to do Node *head = (Node*) malloc(sizeof(Node));
I have modified your code as shown below. You can try running it and co-relate above points.
typedef struct Node {
int data;
struct Node *next;
} Node;
void Insert(Node **head, int x);
void Insert(Node **head, int x) {
Node *temp = (Node*) malloc(sizeof(Node));
temp->data = x;
temp->next = *head;
printf("temp->next address: %d\n", temp->data); // also 100
*head = temp;
printf("%d\n", (*head)->data); // not 100, something else i.e 200
}
int main() {
Node *head = NULL;
head = NULL;
Insert(&head, 25);
printf("head in main(): %d\n", head->data); // For example: 100
return 0;
}
I am trying to print the length of a linked list I created in another .c file called linklist.c from the main.c file. It is not working and I believe is has something to do with pointers and/or memory management over all. I call into question the heap mainly here. some guidance would be appreciated.
#include <stdio.h>
#include <stdlib.h>
#include "node.h"
int main()
{
printf("Hello world!\n");
struct node* mylist = BuildOneTwoThree();
int length = Length(mylist);
printf(mylist->data);
printf(length);
return 0;
}
#include "node.h"
#include <stdio.h>
#include <stdlib.h>
// Return the number of nodes in a list (while-loop version)
int Length(struct node** head) {
int count = 0;
struct node* current = head;
while (current != NULL) {
count++;
current = current->next;
}
return(count);
}
/*
Build the list {1, 2, 3} in the heap and store
its head pointer in a local stack variable.
Returns the head pointer to the caller.
*/
struct node* BuildOneTwoThree() {
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = malloc(sizeof(struct node)); // allocate 3 nodes in the heap
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));
head->data = 1; // setup first node
head->next = second; // note: pointer assignment rule
second->data = 2; // setup second node
second->next = third;
third->data = 3; // setup third link
third->next = NULL;
// At this point, the linked list referenced by "head"
// matches the list in the drawing.
return head;
}
/*
Takes a list and a data value.
Creates a new link with the given data and pushes
it onto the front of the list.
The list is not passed in by its head pointer.
Instead the list is passed in as a "reference" pointer
to the head pointer -- this allows us
to modify the caller's memory.
*/
void Push(struct node** headRef, int data) {
struct node* newNode = malloc(sizeof(struct node));
newNode->data = data;
newNode->next = *headRef; // The '*' to dereferences back to the real head
*headRef = newNode; // ditto head points to new node
}
// Given a list and an index, return the data
// in the nth node of the list. The nodes are numbered from 0.
// Assert fails if the index is invalid (outside 0..lengh-1).
int GetNth(struct node* head, int index) {
struct node* current = head;
int answer = 0;
int x = index;
if(x <= 0 || x >= sizeof(head)-1 )
{
return -1;
}
for(int i = 0; i <= sizeof(head)-1; i++){
if (i == x){
return current->data;
}
current = current->next;
}
}
As you can see I use the BuildOneTwoThree function to build the linkedlist and am writing appropriate functions...It crashes when I try to access mylist into output.
For the most part the code seems to function from the point of view of the question only, printf had to be properly formatted.
printf("%i", length);
type cast malloc required
Change **head to *head in function argument Length
Use proper printf statement.
This question is limited to printing lenght of link list. please find code below:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node* BuildOneTwoThree();
int Length(struct node* head);
int main()
{
printf("Hello world!\n");
struct node* mylist = BuildOneTwoThree();
int length = Length(mylist);
printf("data =%d\n",mylist->data);
printf("length = %d",length);
return 0;
}
// Return the number of nodes in a list (while-loop version)
int Length(struct node* head) {
int count = 0;
struct node* current = head;
while (current != NULL) {
count++;
current = current->next;
}
return(count);
}
/*
Build the list {1, 2, 3} in the heap and store
its head pointer in a local stack variable.
Returns the head pointer to the caller.
*/
struct node* BuildOneTwoThree() {
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = (struct node *)malloc(sizeof(struct node)); // allocate 3 nodes in the heap
second = (struct node *)malloc(sizeof(struct node));
third = (struct node *)malloc(sizeof(struct node));
head->data = 1; // setup first node
head->next = second; // note: pointer assignment rule
second->data = 2; // setup second node
second->next = third;
third->data = 3; // setup third link
third->next = NULL;
// At this point, the linked list referenced by "head"
// matches the list in the drawing.
return head;
}
I'm trying this simple code which asks a user for string input. As it receives an input it then tries to copy each element of the string into different location in a linked list. Everything works just fine (I think) but when i print the linked list, the screen doesnt show any out put. Any idea why is this happening?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node {
char data;
struct node* next;
};
struct node* head = NULL;
void insert(char);
void print();
void main() {
char str1[20];
int i;
printf("Enter the string\n");
fgets(str1,20,stdin);
int len = strlen(str1);
printf("%d\n",len);
for(i=0;i<len;i++) {
insert(str1[i]);
}
print();
}
void insert(char str) {
struct node* temp = (struct node*)malloc(sizeof(struct node));
struct node* temp1 = head;
while(temp1!=NULL) {
temp1 = temp1->next;
}
temp->data = str;
temp1 = temp;
}
void print() {
struct node *temp;
temp = head;
while(temp!=NULL) {
printf("%c ",temp->data);
temp = temp->next;
}
}
You never set head to anything, it will always be NULL. So, you're not creating a list, but a group of unlinked floating nodes.
On another note, don't cast the result of malloc
On yet another note, no need to go through the entire list for every insert - you can keep a tail pointer along with the head, so adding to the end is done without a loop.
void insert(char str) {
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->data = str;
temp->next = NULL;
if(head){//head != NULL
struct node* temp1 = head;
while(temp1->next != NULL) {//search last element
temp1 = temp1->next;
}
temp1->next = temp;//insert new node
} else {
head = temp;//if head == NULL then replace with new node
}
}
How will I free the nodes allocated in another function?
struct node {
int data;
struct node* next;
};
struct node* buildList()
{
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = malloc(sizeof(struct node));
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
return head;
}
I call the buildList function in the main()
int main()
{
struct node* h = buildList();
printf("The second element is %d\n", h->next->data);
return 0;
}
I want to free head, second and third variables.
Thanks.
Update:
int main()
{
struct node* h = buildList();
printf("The element is %d\n", h->next->data); //prints 2
//free(h->next->next);
//free(h->next);
free(h);
// struct node* h1 = buildList();
printf("The element is %d\n", h->next->data); //print 2 ?? why?
return 0;
}
Both prints 2. Shouldn't calling free(h) remove h. If so why is that h->next->data available, if h is free. Ofcourse the 'second' node is not freed. But since head is removed, it should be able to reference the next element. What's the mistake here?
An iterative function to free your list:
void freeList(struct node* head)
{
struct node* tmp;
while (head != NULL)
{
tmp = head;
head = head->next;
free(tmp);
}
}
What the function is doing is the follow:
check if head is NULL, if yes the list is empty and we just return
Save the head in a tmp variable, and make head point to the next node on your list (this is done in head = head->next
Now we can safely free(tmp) variable, and head just points to the rest of the list, go back to step 1
Simply by iterating over the list:
struct node *n = head;
while(n){
struct node *n1 = n;
n = n->next;
free(n1);
}
One function can do the job,
void free_list(node *pHead)
{
node *pNode = pHead, *pNext;
while (NULL != pNode)
{
pNext = pNode->next;
free(pNode);
pNode = pNext;
}
}
struct node{
int position;
char name[30];
struct node * next;
};
void free_list(node * list){
node* next_node;
printf("\n\n Freeing List: \n");
while(list != NULL)
{
next_node = list->next;
printf("clear mem for: %s",list->name);
free(list);
list = next_node;
printf("->");
}
}
You could always do it recursively like so:
void freeList(struct node* currentNode)
{
if(currentNode->next) freeList(currentNode->next);
free(currentNode);
}