如何在此代码中正确地分配内存?

时间:2019-05-03 17:58:52

标签: c malloc heap free

我正在从事C作业,发现无法分配未分配的内存非常混乱。

我一直试图在代码上的不同位置放置free()函数,只是为了检查它是否可以工作,但还没有一次尝试成功。

这是结构和用于它的函数; 下面的所有功能都在一个名为state.c的文件中- stateAdd调用stateNodeCreate-

typedef struct node_t {
    int id;
    const char* name;
    const char* song;
    Set votes;
    Set grades;
    int top_grade;
}*StateNode;

void stateNodeDestroy(StateNode node) {
    if(node == NULL) {
        return;
    }
    if(node->votes) {
        setDestroy(node->votes);
    }
    if(node->grades) {
        setDestroy(node->grades);
    }
    free(node);
}


static StateNode stateNodeCreate(int id,const char* name,const char* song) {
    StateNode state = (StateNode)malloc(sizeof(*state));
    if(state == NULL) {
        return NULL;
    }
    state->id = id;
    state->name = name;
    state->song = song;
    state->top_grade = -1;
    Set votes_set = setCreate(copyVoteElement,
                              freeVoteElement, compareVotes);
    if(votes_set == NULL) {
        free(state);
        return NULL;
    }
    state->votes = votes_set;
    Set grades_set = setCreate(copyGradeElement,
                               freeGradeElement, compareGrades);
    if(grades_set == NULL) {
        stateNodeDestroy(state);
        setDestroy(grades_set);
        return NULL;
    }
    state->grades = grades_set;
    return state;
}

stateResult StateAdd(Set states, int stateId, const char* stateName, const char* songName) {
    if (states == NULL) {
        return STATE_NULL_ARGUMENT;
    }
    if(stateId < 0 ) {
        return STATE_INVALID_ID;
    }
    if(!IsValidName(stateName) || !IsValidName(songName)) {
        return STATE_INVALID_NAME;
    }
    StateNode state_exist = findState(states,stateId);
    if(state_exist != NULL) {
        return STATE_STATE_ALREADY_EXIST;
    }
    free(state_exist);
    StateNode new_state = stateNodeCreate(stateId,stateName,songName);
    if(new_state == NULL) {
        return STATE_OUT_OF_MEMORY;
    }

    if(setAdd(states,new_state) == SET_OUT_OF_MEMORY) {
        stateNodeDestroy(new_state);
        setDestroy(states);
        return STATE_OUT_OF_MEMORY;
    }
    return STATE_SUCCESS;
}

setDestroys使用setCreate销毁一个已经建立的集合,并且setCreate以函数指针作为参数,并使用这些函数从集合(ADT)中复制/释放数据

以下是另一个文件的功能:eurovision.c: eurovisionAddState调用state.c文件中存在的stateAdd-

typedef struct eurovision_t {
    Set states;
    Set judges;
} *Eurovision;

EurovisionResult eurovisionAddState(Eurovision eurovision, int stateId, const char *stateName, const char *songName) {
    stateResult result = StateAdd(eurovision->states, stateId, stateName, songName);
    if (result == STATE_NULL_ARGUMENT) {
        return EUROVISION_NULL_ARGUMENT;
    }
    if (result == STATE_OUT_OF_MEMORY) {
        //setDestroy(eurovision->judges);
        eurovisionDestroy(eurovision);
        return EUROVISION_OUT_OF_MEMORY;
    }
    if (result == STATE_INVALID_ID) {
        return EUROVISION_INVALID_ID;
    }
    if (result == STATE_STATE_ALREADY_EXIST) {
        return EUROVISION_STATE_ALREADY_EXIST;
    }
    if (result == STATE_INVALID_NAME) {
        return EUROVISION_INVALID_NAME;
    }
    return  EUROVISION_SUCCESS;

}

void eurovisionDestroy(Eurovision eurovision) {
    if (eurovision == NULL) {
        return;
    }
    if(eurovision->judges != NULL) {
        setDestroy(eurovision->judges);
    }
    if(eurovision->states != NULL) {
        setDestroy(eurovision->states);
    }
    free(eurovision);
}

eurovisionDestroy清除参数eurovision内部的Sets 并释放eurovision元素。 最后一部分是test.c中存在的该函数: 函数testAddState调用存在于eurovision.c文件中的函数eurovisionAddState-

bool testAddState() {
  Eurovision eurovision = setupEurovision();
  CHECK(eurovisionAddState(eurovision, 0, "israel", "home"), EUROVISION_SUCCESS);
  //CHECK(eurovisionAddState(eurovision, 1, "malta", "chameleon"), EUROVISION_SUCCESS);
  //CHECK(eurovisionAddState(eurovision, 0, "croatia", "the dream"), EUROVISION_STATE_ALREADY_EXIST);
  //CHECK(eurovisionAddState(eurovision, 0, "israel", "home"), EUROVISION_STATE_ALREADY_EXIST);
  //CHECK(eurovisionAddState(eurovision, -1, "croatia", "the dream"), EUROVISION_INVALID_ID);
  eurovisionDestroy(eurovision);
  return true;
}

毕竟,当使用valgrind检测内存泄漏时,仍然表明在这段代码中存在内存泄漏。 瓦尔格朗德说:

48 bytes in 1 blocks are definitely lost in loss record 1 of 1
==10451==    at 0x4C29BC3: malloc (vg_replace_malloc.c:299)
==10451==    by 0x402A71: stateNodeCreate (state.c:124)
==10451==    by 0x402DA9: StateAdd (state.c:236)
==10451==    by 0x40082D: eurovisionAddState (eurovision.c:49)
==10451==    by 0x4015E9: testAddState (eurovisionTests.c:169)
==10451==    by 0x4027CE: main (eurovisionTestsMain.c:15)

这不是全部代码,我非常肯定其余部分的工作情况还不错,不会导致这段代码出现任何内存泄漏。 有什么想法吗?

0 个答案:

没有答案