所以,我有一个数组的结构,叫做 vitorias
英文为 "victories"),一个结构的数组和该结构的数组以及一个字符串的数组。
结构和数组。
char **sistema_eq;
typedef struct
{
int id;
char nome[MAX_CHARS];
int vit;
} vitorias;
问题是,当我使用 cppcheck
它给出了一个错误的说法。
(error) Common realloc mistake: 'conj_vit' nulled but not freed upon failure
(error) Common realloc mistake: 'sistema_eq' nulled but not freed upon failure
(error) Common realloc mistake: 'conj_jogos' nulled but not freed upon failure
而且,如果我使用 Valgrind
它说我做了10个分配和2个释放,但我不明白有什么问题,因为我认为最后我释放了所有的东西。
程序。
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024 /* max characters of a word */
#define MAX_SIZE 5
static int size_until = 0; /*conts the size of sistema_eq and conj_vit*/
static int line = 1; /* counts the number of lines of the stdin */
int ident = 0; /*conts the id of jogos*/
static int size_until = 0; /*counts the size of sistema_eq*/
static int size_until2 = 0;/*counts the size of conj_jogos*/
void a(char nome_jg[],char team1[],char team2[],int score1,int score2);
void A(char nome[]);
char **sistema_eq;
jogo *conj_jogos;
vitorias *conj_vit;
int main()
{
char c;
char nome_jg[MAX_CHARS], team1[MAX_CHARS], team2[MAX_CHARS];
int score1;
int score2;
int i;
conj_jogos = (jogo*)calloc(MAX_SIZE,sizeof(jogo));
memset(conj_jogos,0, MAX_SIZE*sizeof(jogo));
conj_vit = (vitorias*)calloc(MAX_SIZE,sizeof(vitorias));
memset(conj_vit,0, MAX_SIZE*sizeof(vitorias));
sistema_eq = (char**)calloc(MAX_SIZE,sizeof(*sistema_eq));
memset(sistema_eq,0, MAX_SIZE*sizeof(*sistema_eq));
for(i=0;i<MAX_SIZE;i++)
{
sistema_eq[i] = (char*)calloc(1024,sizeof(char));
memset(sistema_eq[i],0, sizeof(char)*1024);
}
while ((c = getchar())!= 'x') {
switch (c)
{
case 'A':
{
scanf("%1023[^:\n]",nome_jg);
remove_esp(nome_jg);
A(nome_jg);
break;
}
case 'a':
{
scanf("%1023[^:\n]:%1023[^:\n]:%1023[^:\n]:%d:%d",nome_jg,team1,team2,&score1,&score2);
remove_esp(nome_jg);
a(nome_jg,team1,team2,score1,score2);
line++;
break;
}
}
}
free(conj_vit);
free(conj_jogos);
free(sistema_eq);
return 0;
}
/*This functions adds a victory and a equipa (team in english) into the corresponding arrays and updates the vitories of each team*/
//Example in El Classico Barcelona vs Real Madrid 1:0, which means Barcelona won
void A(char nome[])
{
if (nome_in_sis(nome) == 1)
{
printf("%d Equipa existente.\n",line);
line++;
}
else
{
if (size_until < MAX_SIZE)
{
strcpy(sistema_eq[size_until],nome);
strcpy(conj_vit[size_until].nome,nome);
conj_vit[size_until].id = size_until;
size_until++;
line++;
}
else
{
conj_vit = realloc(conj_vit,sizeof(vitorias)*(size_until+1));
sistema_eq = realloc(sistema_eq,sizeof(char*)*(size_until+1));
sistema_eq[size_until] = calloc(1024,sizeof(char*));
strcpy(sistema_eq[size_until],nome);
strcpy(conj_vit[size_until].nome,nome);
conj_vit[size_until].id = size_until;
size_until++;
line++;
}
}
}
/*This functions adds a jogo (game in english) and a equipa (team in english) into the array conj_jogos (the array of jogos)*/
void a(char nome_jg[],char team1[],char team2[],int score1,int score2)
{
int vit;
if (jogo_in(nome_jg) == 1)
{
printf("%d Jogo existente.\n",line);
line++;
}
else if ((nome_in_sis(team1) == 0) || (nome_in_sis(team2) == 0))
{
printf("%d Equipa inexistente.\n",line);
line++;
}
else
{
if (size_until2 < MAX_SIZE)
{
conj_jogos[size_until2] = cria_jogo(nome_jg,team1,team2,score1,score2);
if (score1 > score2)
{
vit = procura_vit(team1);
conj_vit[vit].vit++;
}
else
{
vit = procura_vit(team2);
conj_vit[vit].vit++;
}
size_until2++;
}
else
{
size_until2++;
conj_jogos = realloc(conj_jogos,sizeof(jogo)*(size_until2+1));
conj_jogos[size_until2] = cria_jogo(nome_jg,team1,team2,score1,score2);
if (score1 > score2)
{
vit = procura_vit(team1);
conj_vit[vit].vit++;
}
else
{
vit = procura_vit(team2);
conj_vit[vit].vit++;
}
size_until2++;
}
}
}
很抱歉,如果代码看起来很乱,谢谢你的帮助。
正如评论中指出的那样,你从来没有 free
的数据,您用 calloc
在 for
循环。将这个循环(或类似的循环)添加到你的 main
:
//...
for(i=0;i<MAX_SIZE;i++) free(sistema_eq[i]); // MUST be before the next line!
free(sistema_eq);
//...
另外,当你使用 calloc
,你不需要任何的 memset
调用! 从链接的文档中可以看到 void* calloc( size_t num, size_t size )
:
为大小为num的对象数组分配内存,并将分配的内存中的所有字节初始化为零。
报告的 "错误 "涉及 realloc
呼叫:在呼叫的情况下 realloc
失败,您使用的代码将阻止后续释放的 原有 数据 是 指针中的),因为它的地址将被替换为 NULL
在这样的失败中!为了防止这种情况发生,可以使用临时指针,像这样: 为了防止这种情况发生,可以使用一个临时指针,像这样。
jogo* temp_jogo = realloc(conj_jogos,sizeof(jogo)*(size_until2+1));
if (temp_jogo != NULL) conj_jogos = temp_jogo;
else {
// In case of failure, we now still have the original conj_jogos
// pointer, which we can then pass to "free" at some point, presumably
// after we've signalled and/or handled the allocation error.
}
最后(我想),你可能会喜欢读这个: 我是否要投掷malloc的结果? - 的结果,这对调用 calloc
和 realloc
.