Я работаю над домашним заданием на Си, и мне довольно сложно определить, какая память не была выделена.
Я пытался разместить функцию 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 вызывает stateAdd, который существует в файле state.c -
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 очищает Наборы внутри параметра Евровидение
и освобождает элемент Евровидения.
И последняя часть - это функция, которая существует в test.c:
Функция testAddState вызывает функцию eurovisionAddState, которая существует в файле eurovision.c -
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)
Это не весь код, я очень уверен, что остальное работает просто отлично, чтобы не вызвать утечек памяти для этого куска кода.
Есть идеи?