The error is that it prints out the memory instead the values of each node. I tried all combinations of pointers and different printing styles but they all show up as memory leaks.
Here is my code:
#include <stdio.h>//headers
#include <stdlib.h>
struct node{
int val;
struct node *next;
};//linked list
struct node *curr = NULL;//list pointers
struct node *prev = NULL;
struct node *head = NULL;
int main(){
int i;
struct node *curr = (struct node*) malloc(sizeof(struct node));
head=curr;//sets head node
for (i=1;i<=5;i++){
curr->val=i;//sets data
struct node *prev = (struct node*) malloc(sizeof(struct node));
curr->next=prev;
curr=prev;//links to previous node
printf("%d\n", *curr);//prints out data
}
return 0;
}
Well, you have no calls to free in your program, so yes, every call to malloc is technically a leak. That said, I think you are confusing your terms here.
If you want to print out the value of the node, use cur->val, not *cur. *cur returns a struct node, which you are telling printf to interpret as an int.
You should print the value accessing it directly like this
printf("%d\n", curr->val);
Plus you are not setting the value of prev at any point so curr = prev; and then printf("%d\n", curr->val); will just print rubbish.
There are several things wrong apart from the way you access the val field, which as has been commented should be curr->val.
Your program, when thus corrected, prints rubbish because you only print it after pointing curr to prev, and val is uninitialised.
curr->val = i;
...
curr = prev;
printf ("%d\n", curr->val);
Also, you have declared curr and prev both globally and within the function.
I have simplified this, printing the list after it has been created. If you want a different sequence, reverse the i loop. Note I have removed prev.
#include <stdio.h>
#include <stdlib.h>
struct node{
int val;
struct node *next;
};
int main(){
int i;
struct node *curr, *head = NULL;
// build the list
for (i=1; i<=5; i++) {
curr = malloc(sizeof(struct node));
curr->val = i;
curr->next = head;
head = curr;
}
// print the list
curr = head;
while (curr) {
printf ("%d\n", curr->val);
curr = curr->next;
}
return 0;
}
You should check the return value from malloc() before using it.
the following code compiles cleanly
caveat: I have not run this code
#include <stdio.h>//headers
#include <stdlib.h>
struct node{
int val;
struct node *next;
};//linked list
struct node *curr = NULL;//list pointers
struct node *prev = NULL;
struct node *head = NULL;
int main()
{
int i;
for (i=1;i<6;i++)
{
// get block
if( NULL == (curr = malloc(sizeof(struct node)) ) )
{ // then, malloc failed
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
// fill in fields
curr->val = i;
curr->next = NULL;
// display val
printf("%d\n", curr->val);//prints out data
if( NULL == head)
{ // then, first node
head = curr;
prev = curr;
}
else
{ // else, after first node
// link in new node
prev->next = curr; // link in new node
} // end if
} // end while
prev = head;
curr = prev;
while( curr )
{ // then, node to free
curr = prev->next;
free(prev);
prev = NULL;
} // end while
return 0;
} // end function: main
Related
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;
}
The console doesnt show the data from my list node.I filled it with chars that i took from a text File.
#include<stdio.h>
#include<stdlib.h>
struct list_node{
char data;
struct list_node* next;
};
typedef struct list_node* node;
node insert_right(node list,char data)
{
node new_node = (node) malloc(sizeof(struct list_node));
new_node->data = data;
new_node->next = list->next;
list->next = new_node;
return new_node;
}
int main()
{
FILE *fr = fopen("dat1.txt","r");
node list = (node) malloc(sizeof(struct list_node));
int i;
while((i = fgetc(fr)) != EOF){
insert_right(list,i);
}
printf("%c",list->data);
}
The main problem i think would be in the insert method.
You are creating a linked list. Each node you create needs to point to either NULL or the next node. You were not quite making the links. Also you were not getting the new_node you you were returning. Also when printing out a list you have to go through each node (like an array).
#include<stdio.h>
#include<stdlib.h>
struct list_node{
char data;
struct list_node* next;
};
typedef struct list_node* node;
node insert_right(node list,char data)
{
node new_node = (node) malloc(sizeof(struct list_node));
new_node->data = data;
list->next = new_node;
new_node->next = NULL;
return new_node;
}
int main()
{
FILE *fr = fopen("dat1.txt","r");
node list = (node) malloc(sizeof(struct list_node));
int i;
node next = list;
while((i = fgetc(fr)) != EOF){
next = insert_right(next,i);
}
node print = list;
while(print != NULL){
printf("%c",print->data);
print = print->next;
}
}
You are allocating memory to a node called list, but yet you do not initialize any value for data, it can be garbage or any character that does not show up in the console.
When you insert a new value, a new node is created and the first one, the "head" so to speak, is still uninitialized even though it is pointing to a second node that has a meaningful data there.
This is your list:
// Node Y (X) indicates the Y-th node that has a X value.
Node1 (garbage) -> Node2 (value) -> Node3 (value) -> garbage
The last node of your list (which is also the first when you create it) should be pointing to NULL instead of being uninitialized.
I am also pretty sure that your list is poor-implemented because the new elements are always being pointed by list, so you lose track of the ones you created before.
Here is a better version, in my opinion:
#include<stdio.h>
#include<stdlib.h>
struct list_node{
char data;
struct list_node* next;
};
typedef struct list_node* node;
void insert_right(node list,char data)
{
node new_node = (node) malloc(sizeof(struct list_node));
node temp = list;
// It runs through the list until it reaches the last node
while(temp->next != NULL) temp = temp->next;
temp->data = data;
temp->next = new_node;
new_node->next = NULL;
}
int main()
{
FILE *fr = fopen("dat1.txt","r");
// List points to only the first element of the list.
node list = (node) malloc(sizeof(struct list_node));
list->next = NULL;
int i;
while((i = fgetc(fr)) != EOF){
insert_right(list,i);
}
while(list != NULL) {
printf("%c",list->data);
list = list->next;
}
}
#include <stdio.h>
#include <stdlib.h>
struct list_node {
char data;
struct list_node* next;
};
int main()
{
FILE *fr = fopen("dat1.txt","r");
struct list_node *list = malloc(sizeof(*list)), *pos = list;
int i;
while ((i = fgetc(fr)) != EOF) {
pos->data = i;
pos->next = malloc(sizeof(*list->next));
pos = pos->next;
}
pos->next = NULL;
while (list->next) {
printf("%c ", list->data);
free(list); /* important!!!! */
list = list->next;
}
putchar('\n');
return 0;
}
I want to insert a node at the beginning of linked list, whenever insertAtBeginning method is called. My code builds well, but i don't get the desired output.
I get the following output:
0------>NULL
The desired output is:
9------>8------>7------>6------>5------>4------>3------>2------>1------>0------>NULL
Following is my code:
#include<stdio.h>
#include<stdlib.h>
struct dll{
int data;
struct dll* previous;
struct dll* next;
};
struct dll* insertAtBeginning(int a, struct dll* head){
if(head == NULL){
head->data = a;
head->previous = NULL;
head->next = NULL;
return head;
}
else{
struct dll *first;
first = (struct dll*) malloc( sizeof(struct dll));
first->data = a;
first->next = head;
head->previous = first;
first->previous = NULL;
head = first;
free(first);
return head;
}
}
void display_from_first(struct dll* head){
struct dll *temp;
temp = head;
printf("\nThe linked list contains: ");
while(temp != NULL) {
printf("%d------>",temp->data);
temp = temp->next;
}
printf("NULL\n");
free(temp);
}
int main(){
int i = 0;
struct dll *head1, *tail1;
head1 = (struct dll*) malloc( sizeof(struct dll));
head1->next = NULL;
head1->previous = NULL;
for(i=0; i<10; i++){
insertAtBeginning(i, head1);
}
display_from_first(head1);
return 0;
}
The code for a doubly linked list is much cleaner if you start with an empty list of two nodes as shown below.
That way you don't have to deal with special cases like if(head==NULL). There's always a node before and after the node that is being inserted (or deleted), so you just hook things up and you're done.
#include <stdio.h>
#include <stdlib.h>
typedef struct s_node Node;
struct s_node
{
Node *prev;
Node *next;
int data;
};
Node *insertAtBeginning( Node *head, int value )
{
// allocate memory for the new node
Node *node = malloc( sizeof(Node) );
if ( node == NULL )
return NULL;
// insert the node at the beginning of the list
Node *temp = head->next;
head->next = node;
temp->prev = node;
// fill in the fields of the node
node->prev = head;
node->next = temp;
node->data = value;
return node;
}
void showList( Node *head )
{
Node *node;
printf( "The list contains: " );
for ( node = head->next; node->next != NULL; node = node->next )
printf( "%d--->", node->data );
printf( "NULL\n" );
}
int main( void )
{
// create an empty list with two nodes
Node head = { NULL , NULL, 0 };
Node tail = { &head, NULL, 0 };
head.next = &tail;
// insert more nodes
for ( int i = 0; i < 10; i++ )
insertAtBeginning( &head, i );
// display the list
showList( &head );
}
There are mainly two problems here :
free(first) : This is not required as you wish to save the memory you just allocated, not delete it.
Your insertAtBeginning() function returns a pointer to head, so in main(), where you are calling this function change it to head1=insertAtBeginning(i, head1); This way your head is also saved.
Here's the code with the two edits :
http://ideone.com/nXwc8z
You have several mistakes here.
1) Your function insertAtBeginning returns pointer to changed list, but you do not update pointer to head of list in the main function.
2) You are freeing just allocated pointer to new node in the insertion function. You think that you are freeing pointer, but actually you say that this place in memory is not needed more and so your node can't be there.
You can't free(first); in insertAtBeginning().
code here.
And btw when you have empty list your display_from_first() prints The linked list contains: 0------>NULL because of
head1 = (struct dll*) malloc( sizeof(struct dll));
head1->next = NULL;
head1->previous = NULL;
in main(). Remove it from main to have correct output
#include<stdio.h>
#include<stdlib.h>
struct node {
int num;
struct node *next;
}*head=NULL, *curr=NULL;
void print(){
curr = head;
while(curr != NULL){
printf("%d\n", curr->num);
curr = curr->next;
}
}
struct node* memAlo(){
return (struct node *)malloc(sizeof(struct node));
}
void addNode(int no){
curr = head;
while(curr != NULL){
curr = curr->next;
}
curr = memAlo();
if(curr == NULL){
printf("\nmemory up\n");
return;
}
else{
curr->num = no;
curr->next = NULL;
printf("%d\n",curr->num);
}
}
void hellop(){
printf("%d", head->num);
}
int main(){
int i;
curr = head;
for(i=1;i<10;i++){
addNode(i);
}
print();
/*head = memAlo();
head->num = 1;
head->next = NULL;
hellop();*/
}
I am sure I have messed up somewhere. The thing is that the head pointer doesn't get the memory allocated by the memAlo() fn() but how to get there? Please help
What I am trying is to create a singly linked list holding numbers from 1 to 9 and to print them using print(). Actually AddNode() is to create single node at the end of the linked list each time the for loop in main() executes.
You set head = NULL at the point where you first defined head. Except in that one place, we never see head on the left-hand side of = anywhere in your program. So of course head is always equal to NULL and never anything else.
You will probably want to insert some code at the start of your addNode function to test whether head == NULL at that point; and if that is true, you will want to assign the result of memAlo() to head instead of curr. You will have to adjust some of the other logic as well.
Your code for allocating a node is wrong. It should create a node, make some space for it, then return it.
struct node *memAlo() {
struct node *nd = malloc(sizeof(*nd));
return nd;
}
This creates a pointer to a node, properly allocates it, then returns it.
Problems I see:
Not dealing with empty list, i.e. when head == NULL.
Creating nodes that are not linked to each other.
curr = memAlo();
allocated memory for a node and returns it to you, but it does not connect the node with anything else.
Try this:
void addNode(int no){
struct node* temp = NULL;
// Deal with an empty list.
if ( head == NULL )
{
head = memAlo();
head->num = no;
head->next = NULL;
}
// Move curr until we reach the last node of the list.
curr = head;
while(curr->next != NULL){
curr = curr->next;
}
temp = memAlo();
if(temp == NULL){
printf("\nmemory up\n");
return;
}
else{
// Link the new node to the previous last node.
temp->num = no;
temp->next = NULL;
printf("%d\n",temp->num);
curr->next = temp;
}
}
It seems that since head is initially NULL, and then you start allocating nodes without saving the address of the first one, you lose the address of the first one, and then can't walk the list from the beginning.
The part you commented out illustrate the problem.
As a side note, there is no free in your program. Remember to always free the memory you alloc
#include<stdio.h>
#include<stdlib.h>
struct node
{
int num;
struct node *next;
};
struct node *head, *curr;
struct node *pos;
void addNode(int n)
{
if(head==NULL)
{
head = (struct node*)malloc(sizeof(struct node));
head->num = n;
head->next = NULL;
curr = head;
}
else
{
while(curr != NULL)
{
pos = curr;
curr = curr->next;
}
curr = (struct node*)malloc(sizeof(struct node));
curr->num = n;
curr->next = NULL;
pos->next = curr;
}
}
void printList()
{
curr = head;
while(curr != NULL)
{
printf("%d",curr->num);
curr = curr->next;
}
}
int main()
{
head = NULL;
curr = head;
int i, a[] = {4,5,1,2,3,9,0};
for(i=0;i<7;i++)
{
addNode(a[i]);
}
curr = head;
printList();
}
This seems to have solved my problem. I figured it out though. Thanks for all your help.
Here is a linked list I am working on, and trying to figure out exactly what each line does. The way I seem to be learning how to program is painstakingly difficult, and I am getting extremely discouraged. Regardless, I understand how the link list works, but I am not understanding what the code is saying and what it exactly is doing to create the structs. For example: I can't understand why would you be assigning a pointer to node (13 and 14), especially when my understand of pointers is that they are used to store memory locations.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct numnode
{
int val;
struct numnode * next;
};
typedef struct numnode node;
main()
{
int i;
node * head;
node * newnode;
head = NULL;
for (i = 1; i <= 10; i++)
{
newnode = (node *) malloc(sizeof(node));
newnode->val = i;
newnode->next = NULL;
if (head == NULL)
{
head = newnode;
}
else
{
newnode->next = head;
head = newnode;
}
}
}
Here are some annotations (and minor edits to reduce the amount of code).
/* Linked list node definition */
struct node {
int val;
struct node * next;
};
int main() {
int i;
struct node *head, *new_node;
head = NULL;
for (i = 1; i <= 10; i++) {
// Allocate a new node and initialize its components (val and next)
new_node = (struct node *) malloc(sizeof(node));
new_node->val = i;
new_node->next = NULL;
// The if block is actually not necessary...
if (head == NULL) {
// If the linked list is empty, set the head pointer to the initial node
head = new_node;
} else {
// Now that you have your new node, connect it. Start:
// head->[current linked list]
// [new_node.next]->NULL
new_node->next = head;
// head->[current linked list]->...
// [new_node.next]->[current linked list]->...
head = newnode;
// head->[new_node.next]->[current linked list]->...
}
}
}
The key thing is that malloc returns a pointer to memory. Each new node is allocated dynamically and thus is a location in memory (not a basic type).
If you fix the statement pointed out by PakkuDon you will find that the code inserts at the head. It will end up with a list whose values descend from 9 down to 1.
pointer is just the thing to tell you where is the value,like a phone number,you can call anyone no matter who there is,as you konw the number.pointer can point to anything(under your access) as you want,no matter it is a int or a struct.
Here is the summary of this code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct numnode
{
int val;
struct numnode * next;
};
typedef struct numnode node;
main()
{
int i;
node * head;
node * newnode;
head = NULL;
for (i = 1; i <= 10; i++)
{
newnode = (node *) malloc(sizeof(node));
newnode->val = i;
newnode->next = NULL;
if (head == NULL) // It'll be NULL first time, as head = NULL.
{
// True # i = 1
head = newnode;
}
else // Afterwards, as head=newnode
{
// New node will be created every time. Till i <= 10.
newnode->next = head;
head = newnode;
}
}
}
It is a simple code though.
PS: It is head == NULL