免费分配的链表

时间:2019-04-19 17:44:45

标签: c valgrind

valgrind说我在2个地方不使用“免费”。 我的程序处理结构的链表,因此,我还有另一个函数通过使用head结构破坏链表。 尽管使用了eurovisionDestroy函数,我应该在哪里释放newState和newJudge?

谢谢。



typedef struct citizen_t{
    int citizenVote;
    struct citizen_t* next;
}*Citizen;

typedef struct state_t{
    int stateId;
    char* stateName;
    char* stateSong;
    Citizen citizenFirst;
    Citizen citizenIterator;
    int citizenSize;
    double score;
    struct state_t* next;
}*State;

typedef struct judge_t{
    int judgeId;
    char *judgeName;
    int judgeResults[NUM_STATES_JUDGES_VOTE];
    struct judge_t* next;
}*Judge;


struct eurovision_t{
    int stateSize;
    int sizeJudges;
    Judge judgeFirst;
    State  stateFirst;
    Judge judgeIterator;
    State  stateIterator;
};


void eurovisionDestroy(Eurovision eurovision){
    if(eurovision == NULL){
        return;
    }

    Citizen tmpCitizen;
    State tmpState;
    Judge tmpJudge;

    if(eurovision->stateSize != 0){
        while(eurovision->stateFirst != NULL){
            if(eurovision->stateFirst->citizenSize != 0 ){
                while(eurovision->stateFirst->citizenFirst != NULL){
                    tmpCitizen = eurovision->stateFirst->citizenFirst->next;
                    free(eurovision->stateFirst->citizenFirst);
                    eurovision->stateFirst->citizenFirst = tmpCitizen;
                }
            }
            tmpState = eurovision->stateFirst->next;
            free(eurovision->stateFirst->stateName);
            free(eurovision->stateFirst->stateSong);
            free(eurovision->stateFirst);
            eurovision->stateFirst = tmpState;
        }
    }

    if(eurovision->sizeJudges != 0){
        while(eurovision->judgeFirst != NULL){
            tmpJudge = eurovision->judgeFirst->next;
            free(eurovision->judgeFirst->judgeName);
            free(eurovision->judgeFirst);
            eurovision->judgeFirst = tmpJudge;
        }
    }

    free(eurovision);
}

我在其中分配新状态(状态结构)的函数,这里不要使用free,而是在上面的destroy函数中

EurovisionResult eurovisionAddState(Eurovision eurovision, int stateId,
                                    const char *stateName,
                                    const char *songName){
    if(eurovision == NULL || songName == NULL || stateName == NULL){
        return EUROVISION_NULL_ARGUMENT;
    }
    if(stateId < 0 ) {
        return EUROVISION_INVALID_ID;
    }
    if(!isValidName(stateName) || !isValidName(songName) ){
        return EUROVISION_INVALID_NAME;
    }
    State newState = malloc(sizeof(*newState));
    if(newState == NULL){
        return EUROVISION_OUT_OF_MEMORY;
    }

    newState->stateName = malloc(sizeof(char)*(strlen(stateName)+1));
    if(newState->stateName == NULL){
        free(newState);
        return EUROVISION_OUT_OF_MEMORY;
    }
    newState->stateSong = malloc(sizeof(char)*(strlen(songName)+1));
    if(newState->stateSong == NULL){
        free(newState->stateName);
        free(newState);
        return EUROVISION_OUT_OF_MEMORY;
    }

    if(eurovision->stateSize == 0){
        newState->stateId = stateId;
        newState->stateName= strcpy(newState->stateName,stateName);
        newState->stateSong = strcpy(newState->stateSong,songName);
        newState->next = NULL;
        newState->score = 0.0;
        newState->citizenSize = 0;
        eurovision->stateFirst = newState;
        eurovision->stateIterator = newState;
        eurovision->stateSize++;
        return EUROVISION_SUCCESS;
    }
    State previousState =  eurovision->stateFirst;
    eurovision->stateIterator = eurovision->stateFirst;
    for(int i = 0 ; i < eurovision->stateSize ; i++){
        if( stateId == eurovision->stateIterator->stateId ){
            return EUROVISION_STATE_ALREADY_EXIST;
        }
        previousState = eurovision->stateIterator;
        eurovision->stateIterator = eurovision->stateIterator->next;
    }
    newState->stateId = stateId;
    newState->stateName= strcpy(newState->stateName,stateName);
    newState->stateSong = strcpy(newState->stateSong,songName);
    newState->next = NULL;
    newState->score = 0.0;
    newState->citizenSize = 0;
    eurovision->stateSize++;
    previousState->next = newState;
    return EUROVISION_SUCCESS;
}

valgrind输出:

==23285== HEAP SUMMARY:
==23285==     in use at exit: 228 bytes in 8 blocks
==23285==   total heap usage: 1,549 allocs, 1,541 frees, 30,098 bytes   allocated
==23285== 
==23285== 70 (64 direct, 6 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 8
==23285==    at 0x4C29BC3: malloc (vg_replace_malloc.c:299)
==23285==    by 0x400DBC: eurovisionAddJudge (eurovision.c:263)
==23285==    by 0x4040DC: testAddJudge (eurovisionTests.c:206)
==23285==    by 0x404E24: main (eurovisionTestsMain.c:17)
==23285== 
==23285== 76 (64 direct, 12 indirect) bytes in 1 blocks are definitely lost in loss record 7 of 8
==23285==    at 0x4C29BC3: malloc (vg_replace_malloc.c:299)
==23285==    by 0x40090D: eurovisionAddState (eurovision.c:159)
==23285==    by 0x403B67: testAddState (eurovisionTests.c:172)
==23285==    by 0x404D8C: main (eurovisionTestsMain.c:15)
==23285== 
 ==23285== 82 (64 direct, 18 indirect) bytes in 1 blocks are definitely lost in loss record 8 of 8
 ==23285==    at 0x4C29BC3: malloc (vg_replace_malloc.c:299)
==23285==    by 0x40090D: eurovisionAddState (eurovision.c:159)
==23285==    by 0x403B18: testAddState (eurovisionTests.c:171)
 ==23285==    by 0x404D8C: main (eurovisionTestsMain.c:15)

0 个答案:

没有答案