Reputation: 309
I'm trying to implement a linked list, with a addToFront function to start with. Where here I'm just adding the number 5, to the front of the list. I know that if the list is empty, the list pointer should be Null, however, this does not seem to be the case.
EDITED FILES: I've edited the files( thanks to taskinoor's answer), which now provide the output of
0 5
Instead of
5
I have the header file:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
typedef struct List {
struct list * next;
int value;
int size;
}list;
void addToFront(int num, list **l);
void printList(list * l);
int getSize(list * l);
void initialize(list * l);
void freeList(list *l);
A c file "main.c"
#include "Header.h"
int main() {
list l;
initialize(&l);
addToFront(5, &l);
printList(&l);
_getch();
freeList(&l);
return 0;
}
void printList(list * l) {
list *current = l;
while (current != NULL) {
printf("%d ", current->value);
current = current->next;
}
}
void freeList(list *l) {
list *current = l;
while (current != NULL) {
list *tmp = current;
current = current->next;
free(tmp);
}
}
And an interface c file (which is incomplete)
#include "Header.h"
int getSize(list * l) {
return l->size;
}
void initialize(list * l) {
l->next = NULL;
l->value = 0;
l->size = 0;
}
// need to pass **l to update it
void addToFront(int num, list **l) {
// allocate memory for new node
list *tmp = (list *)malloc(sizeof(list));
tmp->value = num;
// new node should point to whatever head is currently pointing
// even if head is NULL at beginning
tmp->next = *l;
// finally l needs to point to new node
// thus new node becomes the first node
*l = tmp;
}
However, when the addToFront function is called, the if statement is never executed. Which doesn't make sense, if the list is empty, shouldn't the list pointer be null?
Next I tried to manually set l == NULL
in the Initialize function
, but that didn't do anything either. Also, my print function loops infinity, which I presume is an issue with malloc. Any help would be greatly appreciated.
Upvotes: 2
Views: 244
Reputation: 46027
The condition if (l == NULL)
is not true in addToFront
because l
is NOT NULL here. You have called l = malloc(sizeof(list));
at the beginning of the main
which made l
not NULL. There is no need to malloc
and initialize l
in this way. I suppose that by l
you meant the head pointer to the list. This should be NULL at beginning (i.e. do not call malloc
at main
and assign the returned address to l
) and your memory for node should be allocated in addToFront
like this:
// need to pass **l to update it
void addToFront(int num, list **l) {
// allocate memory for new node
list *tmp = (list *) malloc(sizeof(list));
tmp->value = num;
// new node should point to whatever head is currently pointing
// even if head is NULL at beginning
tmp->next = *l;
// finally l needs to point to new node
// thus new node becomes the first node
*l = tmp;
}
Remove malloc
from main
.
int main() {
list *l;
addToFront(5, &l); // pass address of l
printList(l);
// other stuffs
}
And printing will be like this:
void printList(list * l) {
list *current = l;
while (current != NULL) {
printf("%d ", current->value);
current = current->next;
}
}
Finally it is not enough to free only l
. You need to traverse whole list and free every node in it.
void freeList(list *l) {
list *current = l;
while (current != NULL) {
list *tmp = current;
current = current->next;
free(tmp);
}
}
Upvotes: 1
Reputation: 25286
Use:
void addToFront(int num, list **l) {
list *tmp= malloc(sizeof(list));
tmp->value = num;
tmp->next = *l;
*l= tmp;
}
Note: initialize
is not needed. Just pass an empty or non-empty list so main
can just do:
int main()
{
list * l= NULL;
addToFront(5, &l);
...
See ForeverStudent his solution to fix the print bug.
Upvotes: 0
Reputation: 2537
This is because of your printing function. your are only printing the values that have a next node after them. so having only 1 value will not print anything. instead you should have:
void printList(list * l) {
while (l !=NULL)
{
printf("%d ", l->value);
l=l->next;
}
}
also in your addToFront
function, you have a logical error, you are only setting the data and size IF the list passed in is in fact NULL
, which is not the case.
Upvotes: 0
Reputation: 1927
Ok, lets begin from the last part:
I tried to manually set l == NULL in the Initialize function, but that didn't do anything either
Actually it did something, but once you returned from the initialize function, that change was lost. Here's why:
When you say initialize(l), in the initialize function body you get a copy of the original pointer l. Then you make that pointer, point to NULL. When that function returns the original pointer l still points to the initial memory (the one allocated with malloc). If you do want this initialize function to have such behavior, you should change it to:
initalize(list **l)
Regarding the addToFront() function, actually if it was executed, you would get a segfault! You check:
if (l == null)
and if it is, you try to dereference the NULL pointer!
l->value = num;
l->next = NULL;
l->size++;
Lastly, in your print fucntion you do not advance your pointer. You should write something like
l=l->next
in order to work
Upvotes: 1