C不确定应该正确释放什么

时间:2018-12-30 18:52:36

标签: c memory linked-list malloc

我有一个学校作业要准备一个链表,这是我的全部功能,我需要完成免费功能,但是我对C语言还很陌生,所以不确定我到底要释放什么。

这是我的代码:

typedef struct TEmployee
{
    struct TEmployee * m_Next;
    struct TEmployee * m_Bak;
    char * m_Name;
} TEMPLOYEE;

#endif /* __PROGTEST__ */

TEMPLOYEE * newEmployee(const char * name, TEMPLOYEE * next)
{
    TEMPLOYEE* head = NULL;
    head = (TEMPLOYEE *)malloc(sizeof(TEMPLOYEE));
    if(head==NULL)
    {
        return NULL;
    }

    head -> m_Name = strdup(name);
    head -> m_Next = next;
    head -> m_Bak = NULL;

    return head;
}

int getEmpPos(TEMPLOYEE *list, TEMPLOYEE *el){
    int pos = 0;
    TEMPLOYEE *listPos = list;

    while(listPos != NULL){
        if(listPos == el)
            return pos;

        listPos = listPos->m_Next;
        pos++;
    }

    return -1;
}

TEMPLOYEE* getEmpAtPos(TEMPLOYEE* list, int pos)
{
    TEMPLOYEE *toReturn = list;
    for(int i = 0; i < pos; i++){
        toReturn = toReturn->m_Next;
    }

    return toReturn;
}

TEMPLOYEE * cloneList(TEMPLOYEE * src)
{
    TEMPLOYEE* current = src;
    TEMPLOYEE* newList = NULL;
    TEMPLOYEE* tail = NULL;

    while(current != NULL)
    {
        if(newList==NULL)
        {
            newList = (TEMPLOYEE*)malloc(sizeof(TEMPLOYEE));
            newList -> m_Name = (char *)malloc(1 + strlen(current -> m_Name));
            strcpy(newList -> m_Name, current -> m_Name);
            newList -> m_Next = NULL;
            newList -> m_Bak = NULL;
            tail = newList;
        }
        else
        {
            tail -> m_Next = (TEMPLOYEE*)malloc(sizeof(TEMPLOYEE));
            tail = tail -> m_Next;
            tail -> m_Name = (char *)malloc(1 + strlen(current -> m_Name));
            strcpy(tail -> m_Name, current -> m_Name);
            tail -> m_Next = NULL;
        }
        current = current -> m_Next;
    }

    // Clone backups
    current = src;
    tail = newList;

    while(current != NULL){
        if(current -> m_Bak)
        {
            tail -> m_Bak = getEmpAtPos(newList, getEmpPos(src, current->m_Bak));
        }
        else
        {
            tail -> m_Bak = NULL;
        }

        tail = tail -> m_Next;
        current = current -> m_Next;
    }

    return newList;
}

这是我的自由功能,但是通过这种方式,它只会释放一些东西,而不会释放其他东西

void freeList(TEMPLOYEE * src)
{

TEMPLOYEE* tmp;

    while(src != NULL)
    {
        tmp = src;
        src = src -> m_Next;
        free(tmp);
    }
}

非常感谢您的帮助

1 个答案:

答案 0 :(得分:2)

只有两个函数可以分配需要释放的内存。

newEmployee函数使用strdup创建一个必须释放的字符串以及TEMPLOYEE对象本身。

分配内存的另一个函数是cloneList,但是它仅克隆一个列表。如果我们首先可以弄清楚如何正确释放一个列表,则只需要确保释放所有克隆的列表即可确保释放在cloneList中分配的内存。

要正确释放列表,我们需要释放每个TEMPLOYEE对象及其所容纳的m_Name。您的空闲列表功能可以这样修改:

void freeList(TEMPLOYEE * src)
{
    TEMPLOYEE *next = src;
    while (next != NULL) {
        TEMPLOYEE *prev = next;
        next = prev->m_Next;
        free(prev->m_Name);
        free(prev);
    }
}

只要您在所有列表上调用此列表,包括由cloneList创建的列表,就应该释放所有内存。