C Не уверен, что правильно освободить - PullRequest
0 голосов
/ 30 декабря 2018

У меня есть школьное домашнее задание для связанного списка, это все мои функции, и мне нужно закончить бесплатную функцию, но я совершенно новичок в 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 голосов
/ 12 января 2019

Есть только две функции, которые выделяют память, которую необходимо освободить.

Функция 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, вся память должна быть освобождена.

...