我正在从事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)
这不是全部代码,我非常肯定其余部分的工作情况还不错,不会导致这段代码出现任何内存泄漏。 有什么想法吗?