C-Linked List附加功能,内存地址错误

时间:2015-04-17 19:54:13

标签: c++

我试图理解为什么编译器检测到“错误的内存错误” 根据我的理解(Pointer->next != null)应该让我到尾巴的末尾,但为什么当它到达最后一个节点时,它会检测到错误。

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;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

忽略C和C ++的混合。 一个主要问题是你忘记了行

_newNode->next = NULL;

使用malloc创建新节点并初始化name和lastname之后。 没有它,你的while循环不能保证按预期工作。

另一个主要问题是在while之后的函数结束时: while循环循环,直到ptr-> next == NULL。所以它指向最后一个条目。 并且您希望将新节点附加到最后一个条目。

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

除此之外,您的代码不是以强大而可靠的方式编写的。 这是一个略有改进的版本,其中包含重要的检查。

#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.

    }
}