简体   繁体   中英

C-LinkedList Append Function, with Bad Memory Address error

I am trying to understand why the compiler detects a "Bad Memory error" To my understanding ( Pointer->next != null ) should get me to the end of the tail, but why when it gets to the last node, it detects an error.

void Append(Data* head, char* name, char* lastname) { 
    Data* _newNode = (Data*)malloc(sizeof(Data));
    std::strcpy(_newNode->name, name);
    std::strcpy(_newNode->lastname, lastname);
    // Iretator
    Data* prt = head;
    if ((*name != '\0') && (*lastname != '\0')) {
        // find the last node in the list:
        //Special Case
        if (*head->name == '\0') {
            std::strcpy(head->name, name);
            std::strcpy(head->lastname, lastname);
        } else {
            while ((int*)prt->next != NULL) {
                prt = prt->next;
            }
            prt = _newNode;
        }
    }
}

Ignoring the mix of C and C++ here. One major problem is that you forgot the line

_newNode->next = NULL;

after creating a new node with malloc and initializing name and lastname. Without that, your while loop is not guaranteed to work as intended.

The other major problem is at the end of the function after the while: The while loop loops until ptr->next == NULL. So it points to the last entry. And you want to append the new node to the last entry.

ptr = _newNode; // <<-- WRONG!
ptr->next = _newNode; // this is what you need.

Apart from that, your code is not written in a robust and solid way. Here a slightly improved version which contains vital checks.

#define MAX_NAME_LEN 10-1
#define MAX_LAST_NAME_LEN 10-1

void Append(Data *head, char *name, char *lastname) 
{
    // Check preconditions:
    if (NULL == head)
        return;
    if (NULL == name)
        return;
    if (NULL == lastname)
        return;
    if( 0 == strlen(name) )
        return;
    if( 0 == strlen(lastname) )
        return;
    if (MAX_NAME_LEN < strlen(name) || MAX_LAST_NAME_LEN < strlen(lastname))
        return; // too long name or lastname

    // implementation

    // Try to re-use an empty head node.
    if (*head->name == '\0')                        // alien code, covering up for 
    {
        std::strcpy(head->name, name);              // some flaw in the design or other 
        std::strcpy(head->lastname, lastname);      // functions
        return;
    }

    // we need a new one.
    Data *_newNode = (Data*)malloc(sizeof(Data));   // can return NULL, not checked
    if (NULL != _newNode)
    {
        std::strcpy(_newNode->name, name);              // can overwrite memory
        std::strcpy(_newNode->lastname, lastname);      // can overwrite memory
        _newNode->next = NULL;                          // + _newNode->next not initialized to NULL <-- MAIN ERROR!
        // Iretator
        Data *prt = head;
        while (prt->next != NULL)           // (int*) not needed, not good
        {
            prt = prt->next;
        }
        prt->next = _newNode;                       // + the prt points to the last entry 
                                                        // and the new node is appended.
                                                        // the original code was assigning newNode to ptr.

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM