Basically, I am trying to insert a node into the linked list via the append function I'm writing. Although in the function, it appears that my node header has the same value of the address of my first node, after the function closes it turns back to null.
This is my append function:
void append(node* header, node newNode) {
//check if header is NULL
//if not add first value
if (header == NULL) {
header = &newNode;
printf("List val: %p\n", header);
printf("node address: %p\n\n", &newNode);
}
else {
//find last node
node* tmp = header;
while (tmp -> next != NULL) {
tmp = tmp -> next;
}
// inser lastnode.next to be address of new node
tmp -> next = &newNode;
}
}
And then in main, I created a header and node and call this function, and ask to print value of list and address of node a:
node* list = NULL;
node a = {1, NULL};
append(list, a);
printf("%p\n", list);
printf("%p\n", &a);
The output is:
List val: 000000b6779ff900
node address: 000000b6779ff900
0000000000000000
000000b6779ff970
So for some reason, the value of the node* list after the function is still NULL. Still new to this pointer thing, so I am currently having trouble understanding where I am wrong.
Edit: Community bot tells me to provide enough code, so I bet it's something about the node type?
typedef struct node {
int value;
struct node* next;
} node;
Problems in your code:
Your list variable isn't getting updated. You are passing the value of the list (call by value) to the function. If you want to reflect the changes made to the value, you need to update it in the main function. So, drop the return type of append function from void to node* or make list global (the former is preferred).
You are passing the value of the node as an argument to append and accessing its address in the function. This address isn't the address provided to the node at main; rather, it is the address provided to it when append is called. So, pass &a instead of a.
Here is some code I wrote to help you out:
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node* next;
} node;
node* append(node* header, node* new_node){
if(header == NULL){
header = new_node;
return header;
}
node* temp = header;
while(temp -> next != NULL){
temp = temp -> next;
}
temp -> next = new_node;
return header;
}
int main(void){
node* list = NULL; // header
// first node
node* new_node = malloc(sizeof(node));
new_node -> data = 1;
new_node -> next = NULL;
// second node
node* new_node2 = malloc(sizeof(node));
new_node2 -> data = 2;
new_node2 -> next = NULL;
// third node
node* new_node3 = malloc(sizeof(node));
new_node3 -> data = 3;
new_node3 -> next = NULL;
// fourth node
node a = {4, NULL}; // your style :)
// the above can be squeezed to one 'create' function
list = append(list, new_node); // the if condition
list = append(list, new_node2); // the else condition
list = append(list, new_node3); // the else condition
list = append(list, &a);
printf("%d\n", list -> data);
printf("new_node: %p\n", new_node);
printf("%d\n", list -> next -> data);
printf("new_node2: %p\n", new_node2);
printf("%d\n", list -> next -> next -> data);
printf("new_node3: %p\n", new_node3);
printf("%d\n", list -> next -> next -> next -> data);
printf("a: %p\n", &a);
return 0;
}
This is a normal behavior. Actually you are passing a pointer header to the function. When you assign it to a value, you only change the local reference..
You may rather want to pass a pointer to the pointer, expressed as struct node **header and then set it with *header = newNode.
Related
I'm trying to implement a circular linked list in C, however I cant seem to print the nodes one by one. Below is the code for assigning the values and then printing them. Whenever I run it, all it prints out is "NULL". I would like to know what should i do so that it prints out "1 -> 2 -> 3 -> ...."
void tail_insert(struct Node * head, struct Node * tail, int num){
struct Node * p = (struct Node*) malloc(sizeof(struct Node));
p->info = num;
p->next = head;
if (head == NULL) {
head = p;
tail = head ;
}
else{
tail->next = p;
tail = p;
}
}
void print_list(struct Node * head)
{
struct Node * current = head;
while (current != NULL)
{
printf("%d -> ", current->info);
current = current->next;
}
printf("NULL\n");
}
int main(){
struct Node * head = NULL, * tail = NULL;
int num = 0;
int length;
int deletespace;
scanf("%d %d", &length, &deletespace);
for (int i = 1; i < length+1 ; i++){
tail_insert(head, tail, i);
}
print_list(head);
The reason you're not getting nodes printed is because of how pass by value works. When you call tail_insert, you're passing a basic pointer. Dereferencing and modifying this inside the function would modify the values pointed to by head and tail, but not carry changes to the pointers themselves outside the function.
One way of fixing this is to change the head and tail parameters to be pointers to pointers (**) and passing the addresses of those variables where you call the function in main.
I'm trying to build a singly-linked list using a struct with 2 data types: char* and int, as well as next to point to other nodes of course.
I have two functions: addToList, and printList as well as the main method to run everything.
What my code is supposed to do is add a node after the head, and check to see if another node with the same data has already been added. If so, it does not add the new node, while incrementing the count data of the already-linked node.
Then, printList() prints the count data and the char* data of each node.
The first issue is that my char comparison doesn't seem to be working, since duplicate nodes are still added. Then, my printList function does not print the char* data correctly. Here's my code (I made sure to comment it so it's easy to follow along):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Struct for node. Has an extra data variable to keep track of which node is next
// in a singly-linked list.
typedef struct node {
char *str;
unsigned int count;
struct node *next;
} node;
// Creates a HEAD node with NULL data.
node *head = NULL;
// Adds a new node and populates the data.
struct node* addToList(struct node* Listptr, char* word){
struct node* new = malloc(sizeof(struct node));
new->str = malloc(sizeof(char) * 34);
strcpy(new->str, word);
new->count = 1;
new->next = Listptr;
// If the head is NULL, sets the new node as the head.
if(head == NULL){
head = new;
return new;
}
// Sets a node iterator "cur" to the first position.
node *cur = head;
// Sets a node iterator to be one place behind cur.
node *prev;
// Loops through the linked list, in order to count the previous words and determine
// if it is necessary to add another node.
// Otherwise, it sets cur to the next node, and prev to the node cur was just at.
while(cur != NULL){
if(cur->str == new->str){
cur->count++;
new = NULL;
return new;
} else{
prev = cur;
cur = cur->next;
}
}
// Checks to see if cur is NULL, if so, sets the previous node.next to the one we're adding.
if(cur == NULL){
prev->next = new;
return new;
}
}
// Prints out the count and word values of each node.
void printList(){
node* cur = head;
while(cur != NULL){
printf("%d %c\n", cur->count, cur->str);
cur = cur->next;
}
}
int main() {
node* Z = NULL;
char *a = "hello";
char *b = "world.";
char *c = "hello";
addToList(Z, a);
addToList(Z, b);
addToList(Z, c);
printList(Z);
return 0;
}
I expect to get:
2 hello
1 world
But in the console, I get:
1 l
1 (weird symbol)
1
Don't use == to compare strings rather use strcmp().
Change if (cur->str == new->str) to this:
if (strcmp(cur->str, new->str) == 0)
Read this to know more on string compare: How do I properly compare strings?
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;
}
below is my code for singly linked list in c. Can anyone help me with this?
this is my main c file:
#include <stdio.h>
#include <stdlib.h>
#include "myclib.c"
struct mydata
{
int num;
char name;
struct mydata *next;
};
int main()
{
struct mydata *head, *newnode, *temp;
head = (struct mydata*)malloc(sizeof(struct mydata));
newnode = (struct mydata*)malloc(sizeof(struct mydata));
temp = (struct mydata*)malloc(sizeof(struct mydata));
head -> num = 123;
head -> name = 'k';
head -> next = NULL;
newnode -> num = 456;
newnode -> name = 'd';
newnode -> next = NULL;
printf("before.app.head = %p\n",head);
printf("before.app.newnode = %p\n",newnode);
printf("before.app.head->next = %p\n",head -> next);
printf("before.app.newnode->next = %p\n",newnode -> next);
head = (struct mydata*)addNodeAtHead(head, newnode, (newnode -> next));
printf("after.app.head = %p\n",head);
printf("after.app.newnode = %p\n",newnode);
printf("after.app.head->next = %p\n",head -> next);
printf("after.app.node->next = %p\n",newnode -> next);
temp = head;
while(temp != NULL)
{
printf("num : %d\n",temp -> num);
printf("name : %c\n",temp -> name);
temp = temp -> next;
}
free(temp);
free(head);
return 0;
}
this is myclib.c file:
#include <stdio.h>
void * addNodeAtHead(void *head, void *node, void *nodenext)
{
printf("\nbefore.head = %p\n",head);
printf("before.node = %p\n",node);
printf("before.nodenext = %p\n",nodenext);
nodenext = head;
head = node;
printf("after.head = %p\n",head);
printf("after.node = %p\n",node);
printf("after.nodenext = %p\n\n",nodenext);
return head;
}
i am trying to add newnode in front of head and than changing head pointer to newnode.
#include <stdio.h>
#include <stdlib.h>
//#include "myclib.c"
struct mydata
{
int num;
char name;
struct mydata *next;
};
struct mydata* addNodeAtHead(struct mydata* head, struct mydata* node)
{
#ifdef DEBUG
printf("\nbefore.head = %p\n",head);
printf("before.node = %p\n",node);
// printf("before.nodenext = %p\n",nodenext);
#endif
if(node){
node->next = head;
head = node;
}
#ifdef DEBUG
printf("after.head = %p\n",head);
printf("after.node = %p\n",node);
// printf("after.nodenext = %p\n\n",nodenext);
#endif
return head;
}
int main()
{
struct mydata *head, *newnode, *temp;
head = (struct mydata*)malloc(sizeof(struct mydata));
newnode = (struct mydata*)malloc(sizeof(struct mydata));
//temp = (struct mydata*)malloc(sizeof(struct mydata));//unused and rewrite to other pointer
head -> num = 123;
head -> name = 'k';
head -> next = NULL;
newnode -> num = 456;
newnode -> name = 'd';
newnode -> next = NULL;
#ifdef DEBUG
printf("before.app.head = %p\n",head);
printf("before.app.newnode = %p\n",newnode);
printf("before.app.head->next = %p\n",head -> next);
printf("before.app.newnode->next = %p\n",newnode -> next);
#endif
head = (struct mydata*)addNodeAtHead(head, newnode);
#ifdef DEBUG
printf("after.app.head = %p\n",head);
printf("after.app.newnode = %p\n",newnode);
printf("after.app.head->next = %p\n",head -> next);
printf("after.app.node->next = %p\n",newnode -> next);
#endif
temp = head;
while(temp != NULL)
{
printf("num : %d\n",temp -> num);
printf("name : %c\n",temp -> name);
temp = temp -> next;
}
/*
free(temp);//NULL
free(newnode);//...
free(head);//already changed
*/
temp=head;
while(temp != NULL){
struct mydata *prev = temp;
temp=temp->next;
free(prev);
}
return 0;
}
When you are passing (newnode -> next) to the function addNodeAtHead. The value of (newnode -> next) is copied to the node variable in the function. And you are updating that node variable with new value head. After the execution of the function node variable get destroyed and has no relation with (newnode -> next). And so (newnode -> next) remains unchanged.
To over come it, just change your addNodeAtHead like bellow:
void * addNodeAtHead(void *head, void *node)
{
printf("\nbefore.head = %p\n",head);
printf("before.node = %p\n",node);
((mydata *)node)-> next = (mydata *) head;
printf("after.head = %p\n",head);
printf("after.node = %p\n",node);
return node;
}
And call it simply like:
head = (struct mydata*)addNodeAtHead(head, newnode);
And Everything should be okay now.
You need to set the next pointer on the added node to point to the original head node.
I changed the signature of addNodeAtHead: You should not pass void * when you are alyway passing pointers of the type mydata *. I also change the variable names to be more clear (IMO) about their purpose
mydata * addNodeAtHead(mydata * original_head, mydata * new_node)
{
new_node -> next = original_head;
return new_node; // new_node is now the head of the list!
}
**PROGRAM ON SINGLY LINKER LIST ( CREATION AND TRAVERSING WITH COMMENTS )**
#include<stdio.h> //Header file for input and output operations.
#include<conio.h>
struct node // structure declaration .
{
int info; // stores information.
struct node *link; // stores the address of next link.
};
struct node *first; // used to point to the first node.
void create(); // function call |NOTE| This line is optional.
void traverse(); // function call |NOTE| This line is optional.
int main() // main function.
{
create(); // function call for creation.
traverse(); // function call for traversing i.e nothing but display.
return 0;
}
void create() // declaration of create function , creation of nodes.
{
char ch; // variable to take an input from the user for decision.
struct node *ptr,*cpt; // these are used to create a node and referred to as
//previous pointer and current pointer.
ptr=(struct node*)malloc(sizeof(struct node)); //dynamic declaration
printf("Enter data into the first node \n");
scanf("%d",&ptr->info); // taking the input from the user.
first=ptr; //assigning the information taken from previous pointer to first for
//future identification.
do // loop which continuously generates and links new nodes to previous nodes.
{
cpt=(struct node*)malloc(sizeof(struct node)); //dynamic declaration of current
//pointer.
printf("Enter the data for another node \n");
scanf("%d",&cpt->info); // getting input from the user of next node
// information.
ptr->link=cpt; // linking the previous pointer to the new pointer.
ptr=cpt; // transferring the previous node information to the current node
//i.e previous pointer to the current pointer.
printf("Do you want to create another node <Y/N>:\n\n");
ch=getch(); // getting the users decision.
}
while(ch=='y'); // checking the users decision.
ptr->link=NULL; // assigning the previous pointer link to null;
}
void traverse() // function declaration of display or traversing.
{
int count=1; // counting variable for naming the nodes.
struct node *ptr; // pointer variable used for traversing.
ptr=first; // assigning ptr to the first for starting traversing from the
//first node.
printf("TRAVERSING OF A LINKED LIST \n");
while(ptr!=NULL) // checking whether the ptr is null or not, And if not
//executes the statements written in the body.
{
printf("The data stored in node %d is:%d \n",count,ptr->info); //prints the
// node id and information present in the node.
ptr=ptr->link; // This statement is used to traverse to the next node.
count++; // count incrementation.
}
}
// f☺ll☺w ☺n instagram ♥ ---> #cyber_saviour
//------ SINGLY LINKED LIST PROGRAM ( CREATION AND TRAVERSING ) -------X
#include<stdio.h>
#include<conio.h>
struct node
{
int info;
struct node *link;
};
struct node *first;
int main()
{
void create();
void traverse();
create();
traverse();
return 0;
}
void create()
{
struct node *cpt,*ptr;
char ch;
ptr=(struct node*)malloc(sizeof(struct node));
printf("enter the data \n");
scanf("%d",&ptr->info);
first=ptr;
do
{
cpt=(struct node*)malloc(sizeof(struct node));
printf("enter the data \n");
scanf("%d",&cpt->info);
ptr->link=cpt;
ptr=cpt;
printf("Do you want to create a new node <Y/N> :\n");
ch=getch();
}
while(ch=='y');
ptr->link=NULL;
}
void traverse()
{
struct node *ptr;
ptr=first;
while(ptr!=NULL)
{
printf("The entered nodes are:%d \n",ptr->info);
ptr=ptr->link;
}
}
#include <stdio.h>
void addNodeAtHead(void **head, void *node){
void *prH=*head;
*head=node;
node->next=prH;
}
So I have a self-made double-linked-list implementation that is being used as a stand in for a queuer. (implemented in C, a language that I am admittedly weak in).
my typedef for the node:
typedef struct Node
{
char *name;
int data;
int recurring;
struct Node *next;
struct Node *prev;
}node;
which says "a node has a name, a datapoint, whether it's recurring or not and pointers to the previous and next nodes"
the insertion function like so
node * insertFromTail(node *tail, int data, int recurring, char *name)
{
node *newNode;
node *oldNext;
node *origTail = tail;
/*assume *pointer points to tail of list*/
/*printf("tail data is %d\n", tail->data);
printf("before loop\n");*/
while(tail->prev != NULL && tail->data > data)
{
/*printf("inside while loop\n");*/
tail = tail -> prev;
}
/*printf("after loop\n");*/
/*if we are looking at a no item list or tail*/
if(tail->next == NULL)
{
/*printf("pointer is tail\n");*/
return insert(tail, data, recurring, name);
}
else /*tail pointer points at item before the point of insertion*/
{
/*printf("default case\n");
printf("pointer data is %d\n", tail->data);*/
oldNext = tail->next;
newNode = (node *)malloc(sizeof(node));
newNode->data = data;
newNode->recurring = recurring;
newNode->name = name;
oldNext -> prev = newNode;
newNode -> next = oldNext;
tail -> next = newNode;
newNode -> prev = tail;
return origTail;
}
}
with the internal insert
node * insert(node *tail, int data, int recurring, char *name)
{
/* Allocate memory for the new node and put data in it.*/
tail->next = (node *)malloc(sizeof(node));
(tail->next)->prev = tail;
tail = tail->next;
tail->data = data;
tail->recurring = recurring;
tail->name = name;
tail->next = NULL;
return tail;
}
which is passed the tail of the list, the data point, the time at which the next item will recur at and the name of the item.
if we start with a node that is empty and has NULL prev and next references (a dummy node), and I add three unique nodes with a function called ADD that calls insertFromTail taking input from stdIn
int main()
{
node *start,*temp,*tail;
start = (node *)malloc(sizeof(node));
temp = start = tail;
temp->next = NULL;
temp->prev = NULL;
if(strcmp(command, "ADD") == 0)
{
scanf("%d",&argTime);
scanf("%s",&argName);
tail = insertFromTail(head, argTime, 0, *argName);
}
}
with input as so:
INPUT:
ADD 10 Gin
ADD 20 Vodka
ADD 30 Rum
PRINT
I would get an output of
OUTPUT:
Rum 10
Rum 20
Rum 30
This is an error, as the desired output would be
OUTPUT:
Gin 10
Vodka 20
Rum 30
I have a feeling it has to do with how the string is passed into the node, but as you can see, I'm stumped. This is the last thing left on the assignment and everything else is working perfectly, so I decided to ask here to see if anyone can nudge me on the right path. Thanks for your help in advance :)
P.S. Sorry for bad everything, I'm sleep deprived :(
Short answer: you'll need to duplicate that name:
tail->name = strdup(name);
Longer answer: at each iteration you're storing the same pointer. You're storing it and then the next time you're writing to it again. So you end up with 3 identical pointers to whatever you input last.
A simple fix is to duplicate the string and store a copy: precisely what strdup does. But if your implementation lacks strdup, you can try:
tail->name = malloc(strlen(name) + 1);
strcpy(tail->name, name);
Don't forget to check for errors
Don't forget to free the memory at some point