Search code examples
cmallocdynamic-memory-allocation

C - error when allocating dynamic memory for linked list node


I am trying to write a code that reads a text file to a linked list and stores in memory. I don't know why there are errors on malloc functions I use it in my code.

This is the pre-given header file that need to keep as is:

#ifndef ADDRESSBOOK_LIST_H
#define ADDRESSBOOK_LIST_H

#define NULL_SPACE 1

#define NAME_LENGTH (20 + NULL_SPACE)
#define TELEPHONE_LENGTH (10 + NULL_SPACE)

typedef struct telephoneBookNode
{
    int id;
    char name[NAME_LENGTH];
    char telephone[TELEPHONE_LENGTH];
    struct telephoneBookNode * previousNode;
    struct telephoneBookNode * nextNode;
} TelephoneBookNode;

typedef struct telephoneBookList
{
    TelephoneBookNode * head;
    TelephoneBookNode * tail;
    TelephoneBookNode * current;
    unsigned size;
} TelephoneBookList;

This is the code I write to load txt file into memory:

The entry has a format ID, Name, Number like 123, Alice, 0123456789

#include "addressbook_list.h"
TelephoneBookList * createTelephoneBookList(char entry[])
{
    TelephoneBookList* aList = NULL;
    TelephoneBookNode* aNode = createTelephoneBookNode();
    char *tokens;

    tokens = strtok(entry, ", ");
    aNode->id = tokens;

    tokens = strtok(NULL, ", ");
    aNode->name = tokens; //Error: array type char[21] is not assignable

    tokens = strtok(NULL, ", ");
    aNode->telephone = tokens; //Error; array type char[11] is not assignable

    aNode->nextNode = aList->head;
    aList->head = aNode;

    if (aList == NULL)
    {
        aNode->nextNode = NULL;
        aNode->previousNode = NULL;

        aList->current = aNode;
        aList->head = aNode;
        aList->tail = aNode;
    }
    else
    {
        aList->tail->nextNode = aNode;
        aNode->nextNode = NULL;

        aList->tail = aList->tail->nextNode;
    }

    return aList;
}

This is the function to create nodes, I got error:

incompatible pointer to integer conversion assigning to 'char' from 'char*', dereferenced with *

TelephoneBookNode * createTelephoneBookNode()
{
    TelephoneBookNode* aNode;

    aNode = (TelephoneBookNode*) malloc(sizeof aNode);

    aNode->id = (int) malloc(sizeof aNode->id);
    aNode->name = (char*) malloc(sizeof aNode->name);
    aNode->telephone = (char*) malloc(sizeof aNode->telephone);

    return aNode;
}

Please someone can explain me a bit on the error. Thank you very much!


Solution

    • They say you shouldn't cast the result of malloc() in C.
    • You cannot assign to arrays, which will be converted to non-lvalue pointer when used as operand of = operator, in C.
    • TelephoneBookNode has two pointers and some other members, but you allocated space for only one pointer. This will cause luck of space and out-of-range access in typical environment.
    • Allocating a memory, converting it to some integer in implemention-defined manner and using it to initializing a menber looks weird.

    Your createTelephoneBookNode() function should be like this:

    TelephoneBookNode * createTelephoneBookNode()
    {
        TelephoneBookNode* aNode;
    
        /* add dereference operator to get the size of what will be pointed by aNode */
        aNode = malloc(sizeof *aNode);
    
        /* do initialization of member if it is required */
    
        return aNode;
    }
    

    strcpy() function is available in string.h to copy strings, and atoi() function is available in stdlib.h to convert strings into integers. Using these, the part that is assigning data to members should be like this:

    tokens = strtok(entry, ", ");
    aNode->id = atoi(tokens);
    
    tokens = strtok(NULL, ", ");
    strcpy(aNode->name, tokens);
    
    tokens = strtok(NULL, ", ");
    strcpy(aNode->telephone, tokens);
    

    Note that error checking is omitted here. Add them to make the program safer.