Leran Dagash
Leran Dagash

Reputation: 65

Generic linked list/Variable is being used without being initialized

So I'm trying to write a generic program for an assignment and the program keeps telling me that the list variable is being used without being initialized. I've tried pretty much everything I could but it still didn't make a difference so if anyone can tell me what I'm doing wrong I'd be extremely grateful.

The code is somewhat long so bear with me on this.

Header contents:

#ifndef _HEADER_H
#define _HEADER_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

typedef enum { FALSE, TRUE } BOOL;

/* defining specific function names*/
typedef int(*compare_func)(void*, void*);
typedef void(*print_func)(void*);
typedef void(*free_func)(void*);

/* defining struct names and pointers*/
typedef struct set Set;
typedef struct set* PSet;
typedef struct list List;
typedef struct list* PList;

/* creating and initialzing a set*/
PList createSet(PList List, compare_func cmp_fnc, print_func prnt_fnc, free_func free_fnc);

/* finding the biggest value in the set*/
void* findMax(PList List);

/* finding the smallest value in the set*/
void* findMin(PList List);

/* finding an element in the set*/
BOOL findInSet(PList List, void* val);

/* function for finding the size of the list*/
int setSize(PList list);

/* inserting a new element.*/
BOOL addToSet(PList List, void *data);

/* deleting an element, pointered by todel*/
BOOL deleteFromSet(PList list, void *todel);

/* print the elements in the set */
void printAll(PList list);

/* deleting the entire set */
void deleteSet(PList list);

#endif

Implementation File:

    #include "Header.h"

typedef struct set      // Set struct for bi-directional list
{
    void* data;
    struct  set *next, *prev;
}Set, *PSet;

typedef struct list      // List struct
{
    int ListSize;
    Set *head;
    Set *tail;
    compare_func compare;
    print_func print;
    free_func free;
}List, *PList;


PList createSet(PList LIST, compare_func cmp_fnc, print_func prnt_fnc, free_func free_fnc)    // Function for initializing and creating a set
{
    PList list;
    list = (PList)malloc(sizeof(List));
    LIST->ListSize = 0;
    LIST->head = NULL;
    LIST->tail = NULL;
    LIST->compare = cmp_fnc;
    LIST->print = prnt_fnc;
    LIST->free = free_fnc;
    return list;
}


void* findMax(PList List)         // Function for finding the biggest value in a set
{
    if (List->head == NULL)     // If the set is empty
        return NULL;

    PSet temp;
    void* max = List->head->data;
    temp = List->head;
    while (temp)
    {
        if (List->compare(temp->data, max) == 1)      // Finding the biggest value
            max = temp->data;
        temp = temp->next;    // Moving to the next node
    }
    return max;
}


void* findMin(PList List)         // Function for finding the smallest value in a set
{
    if (List->head == NULL)        // If the set is empty
        return NULL;

    PSet temp;
    void* min = List->head->data;
    temp = List->head;
    while (temp)
    {
        if (List->compare(temp->data, min) == -1)       // Finding the smallest value
            min = temp->data;
        temp = temp->next;       // Moving to the next node
    }
    return min;
}


BOOL findInSet(PList List, void* val)        // Function for checking whether a given character is in the set
{
    if (List->head == NULL)    // If the list is empty
        return FALSE;

    PSet temp;
    temp = List->head;
    while (temp)
    {
        if (List->compare(temp->data, val) == 0)        // If the character exists
            return TRUE;
        temp = temp->next;     // Moving to the next node
    }
    return FALSE;
}


int setSize(PList list)
{
    return list->ListSize;
}


BOOL addToSet(PList List, void *data)       // Function for adding an item to the set
{
    PSet temp, CurrentNode;
    CurrentNode = List->head;
    temp = (PSet)malloc(sizeof(Set));
    if (temp == NULL)           // If the allocation failed return false
        return FALSE;

    temp->data = data;       // Filling the temp with the data
    temp->next = NULL;
    temp->prev = NULL;

    if (List->head == NULL)      // If the list is empty
    {
        List->head = temp;
        List->tail = temp;
        List->ListSize++;
        return TRUE;
    }
    else {
        while (CurrentNode)          // Loop for checking whether the inserted character exists in the list
        {
            if (List->compare(data, CurrentNode->data) == 0) return FALSE;
            CurrentNode = CurrentNode->next;
        }
        List->tail->next = temp;   // Adding the node to the list
        temp->prev = List->tail;
        List->tail = temp;     // Updating the tail
        List->ListSize++;
        return TRUE;
    }
}


BOOL deleteFromSet(PList list, void *todel)         // Function for deleteing an item from a set
{
    PSet nodeToDel;

    if (list->head == NULL)      // If the list is empty
        return FALSE;

    if (list->compare(todel, list->head->data) == 0)    // If the node to be deleted is the head
    {
        nodeToDel = list->head;
        list->head = list->head->next;
        if (list->head != NULL)
            list->head->prev = NULL;
        list->free(nodeToDel->data);
        free(nodeToDel);
        list->ListSize--;
        return TRUE;
    }
    else if (list->compare(todel, list->tail->data) == 0)         // If the node to be deleted is the tail
    {
        nodeToDel = list->tail;
        list->tail = list->tail->prev;
        list->tail->next = NULL;
        list->free(nodeToDel->data);
        free(nodeToDel);
        list->ListSize--;
        return TRUE;
    }
    else
    {
        nodeToDel = list->head;
        while (nodeToDel->next)      // Any node other than the head or the tail
        {
            if (list->compare(todel, nodeToDel->data) == 0)     // If the character exists in the list
            {
                nodeToDel->next->prev = nodeToDel->prev;
                nodeToDel->prev->next = nodeToDel->next;
                list->free(nodeToDel->data);
                free(nodeToDel);
                list->ListSize--;
                return TRUE;
            }
            nodeToDel = nodeToDel->next;       // Moving to the next node
        }
    }
    return FALSE;      // If the character wasn't found in the list return false
}


void printAll(PList list)        // Funciton for printing all items in a set
{
    PSet temp;
    if (list->head == NULL)      // If the list is empty
        printf("\nThe list is empty.");
    else
    {
        printf("\nThe list is:\n");
        temp = list->head;
        while (temp)       // While there are still nodes left
        {
            list->print(temp->data);   // Call specific function for printing
            temp = temp->next;     // Move to the next node
        }
        printf("\n");
    }
}


void deleteSet(PList list)       // Function for deleting a set
{
    PSet temp;
    if (!(list->head))   // If the list is empty
        printf("\nThe set is empty.");
    else
    {
        while (list->head)
        {
            temp = (list->head);
            list->head = list->head->next;   // Moving to the next node
            if (list->head != NULL)
                list->head->prev = NULL;
            list->free(temp->data);     // Call specific function for freeing memory
            free(temp);
            list->ListSize--;
        }
        printf("The set has been deleted.\n");
    }
}

Main Function:

#include "Header.h"

void prnt_string(void* str)       // specific function for printing strings
{
    puts(*(char*)str);
    printf(" ");
}

void free_string(void* str)     // specific function for freeing memory
{
    free(str);
}

int cmp_str(void* s1, void* s2)     // specific function for comparing two strings
{
    if (strcmp(*(char*)s1, *(char*)s2) == 0)
        return 0;
    else if (strcmp(*(char*)s1, *(char*)s2 == 1))
        return 1;
    else return -1;
}


void prnt_int(void* a)     // Specific function for printing integers
{
    printf("%d ", a);
}

void free_int(void* a)      // Specific funtion for freeing integers
{
    free(a);
}

int int_comp(void* a, void* b)         // Specific function for printing integers
{
    if (*(int*)a == *(int*)b)
        return 0;
    else if (*(int*)a > *(int*)b)
        return 1;
    else return -1;
}


int main()
{
    char ch, tempstr[31], *str;
    int n, option, *num, item;
    void *temp;
    BOOL status;
    PList list;

    printf("Choose the type you want to work with:\n");
    printf("1. Integers\n");
    printf("2. Strings\n");
    printf("Enter input: ");
    scanf("%d", &n);

    switch (n)
    {
    case 1:
        list = createSet(list, int_comp, prnt_int, free_int);
        do
        {
            printf("Choose the desired action: ('-1' to exit)\n");
            printf("1. Create a Set\n");
            printf("2. Add To Set\n");
            printf("3. Delete From Set\n");
            printf("4. Find an Item in The Set\n");
            printf("5. Find The Biggest Value In The Set\n");
            printf("6. Find The Smallest Value In The Set\n");
            printf("7. Delete The Set\n");
            printf("Enter input: ");
            scanf("%d", &option);

            switch (option)
            {
            case 1:
                list = createSet(list, int_comp, prnt_int, free_int);
                printf("The Set Has Been Initialized.\n");
                break;
            case 2:
                num = (int*)malloc(sizeof(int));
                if (num == NULL)
                {
                    printf("Memory allocation failed!");
                    deleteSet(list);
                    return 1;
                }
                else
                {
                    printf("Enter a number: ");
                    scanf("%d", &num);
                    status = addToSet(list, num);
                    if (status == TRUE)
                    {
                        printf("Number successfully added to set.\n");
                        printAll(list);
                    }
                    else
                    {
                        printf("Operation failed!\nThe number already exists in the set or memory allocation failed.\n");
                        deleteSet(list);
                        return 1;
                    }
                }
                break;
            case 3:
                printf("Enter number: ");
                scanf("%d", &item);
                status = deleteFromSet(list, &item);
                if (status == TRUE)
                {
                    printf("Number successfully deleted.\n");
                    printAll(list);
                }
                else
                {
                    printf("Operation failed!\nThe number does not exist in the set.");
                    printAll(list);
                }
                break;
            case 4:
                printf("Enter number: ");
                scanf("%d", &item);
                if (findInSet(list, &item) == TRUE)
                    printf("Item exists in the set.\n");
                else if (findInSet(list, &item) == FALSE) printf("Item does not exist in the set.\n");
                /*else if (findInSet(list, &item) == NULL) printf("The set is empty.\n");*/
                break;
            case 5:
                printf("The size of the set is %d", setSize(list));
                break;
            case 6:
                temp = findMax(list);
                if (temp == NULL) printf("The set is empty.\n");
                else printf("The biggest value in the set is %d", (int*)temp);
                break;
            case 7:
                temp = findMin(list);
                if (temp == NULL) printf("The set is empty.\n");
                else printf("The smallest value in the set is %d", (int*)temp);
                break;
            case 8:
                deleteSet(list);
                break;
            }
        } while (option != -1);
        deleteSet(list);
        break;
    case 2:
        list = createSet(list, cmp_str, prnt_string, free_string);
        do
        {
            printf("Choose the desired action: ('-1' to exit)\n");
            printf("1. Create a Set\n");
            printf("2. Add To Set\n");
            printf("3. Delete From Set\n");
            printf("4. Find an Item in The Set\n");
            printf("5. Find The Biggest Value In The Set\n");
            printf("6. Find The Smallest Value In The Set\n");
            printf("7. Delete The Set\n");
            printf("Enter input: ");
            scanf("%d", &option);

            switch (option)
            {
            case 1:
                list = createSet(list, cmp_str, prnt_string, free_string);
                printf("The Set Has Been Initialized.\n");
                break;
            case 2:
                    printf("Enter a string(max of 30 characters): ");
                    gets(tempstr);
                    str = (char*)malloc(strlen(tempstr) + 1 * sizeof(char));
                    if (str == NULL)
                    {
                        printf("Memory allocation failed!\n");
                        deleteSet(list);
                        return 1;
                    }
                    strcpy(str, tempstr);
                    status = addToSet(list, str);
                    if (status == TRUE)
                    {
                        printf("String successfully added to set.\n");
                        printAll(list);
                    }
                    else
                    {
                        printf("Operation failed!\nThe string already exists in the set or memory allocation failed.\n");
                        deleteSet(list);
                        return 1;
                    }
                break;
            case 3:
                printf("Enter string(max of 30 characters): ");
                gets(tempstr);
                status = deleteFromSet(list, &tempstr);
                if (status == TRUE)
                {
                    printf("String successfully deleted.\n");
                    printAll(list);
                }
                else
                {
                    printf("Operation failed!\nThe string does not exist in the set.");
                    printAll(list);
                }
                break;
            case 4:
                printf("Enter string: ");
                gets(tempstr);
                if (findInSet(list, &tempstr) == TRUE)
                    printf("Item exists in the set.\n");
                else if (findInSet(list, &tempstr) == FALSE) printf("Item does not exist in the set.\n");
                /*else if (findInSet(list, &tempstr) == NULL) printf("The set is empty.\n");*/
                break;
            case 5:
                printf("The size of the set is %d", setSize(list));
                break;
            case 6:
                temp = findMax(list);
                if (temp == NULL) printf("The set is empty.\n");
                else
                {
                    printf("The biggest value in the set is ");
                    puts((char*)temp);
                }
                break;
            case 7:
                temp = findMin(list);
                if (temp == NULL) printf("The set is empty.\n");
                else
                {
                    printf("The smallest value in the set is ");
                    puts((char*)temp);
                }
                break;
            case 8:
                deleteSet(list);
                break;
            }
        } while (option != -1);
        deleteSet(list);
        break;
    default:
        printf("Wrong input!\n");
        break;
    }

    getch();
    return 0;
}

When I try running the program I get the error message that the list variable in the main function is being used without being initialized though I fail to understand why it needs initializing in the first place. What could the problem be?

Upvotes: 0

Views: 48

Answers (1)

nullp0tr
nullp0tr

Reputation: 485

Every variable should be initialized before being read, because otherwise anything you read from it is garbage. In C variables don't get initialized by default like in some other languages.

In your createSet() function you dereference the variable LIST, but list in main was just declared as a pointer without initializing it to actually point at something.

You should use List in main to declare List list and not PList list. Then pass &list to the functions that take a PList argument.

Also your current createSet() function is mixing two ways of initializing objects together.

You can pass a PList to it and then initialize the List that the PList points to, so:

List fooList;
PList pFooList = &fooList;
createSet(pFooList, ...):

and then in createSet() don't allocate a new object with malloc.

But you can also create the object in createList() but then don't pass it any PList.

The advantage of the first option is that if you wanna dynamically allocate the object you can do it with:

PList pFooList = malloc(sizeof(List));
createSet(pFooList, ...);

but you don't have to, since you can still allocate the object on the stack.

Note

As @MichaelBeer commented, variables declared static actually get automatically initialized, but this wouldn't have solved the problem of the asker, since if list was declared with static PList list, then list would point to NULL instead of just garbage.

Upvotes: 3

Related Questions