TTEd
TTEd

Reputation: 309

Adding to the front of a Simple Linked List

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

Answers (4)

taskinoor
taskinoor

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

Paul Ogilvie
Paul Ogilvie

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

ForeverStudent
ForeverStudent

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

sestus
sestus

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

Related Questions