C noob over here. Created a program that simulates a soccer team to help me get a handle on memory allocation. My program works but valgrind is telling me that I have a memory leak in the methods "create_player" and "add_player_to_club"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 8
typedef struct player {
int id;
char *position;
} Player;
typedef struct club {
int size;
Player *team[SIZE];
} Club;
Player *create_player(int id, const char *description);
void create_team(Club *club);
void print_club(const Club *club);
void destroy_player(Player *player);
void add_player_to_club(Club *club, int id, const char *position);
void destroy_club(Club *club);
int main() {
Club club;
create_team(&club);
add_player_to_club(&club, 1, "forward");
add_player_to_club(&club, 2, "goalie");
print_club(&club);
destroy_club(&club);
return 0;
}
Player *create_player(int id, const char *description){
Player *player;
player = malloc(sizeof(Player));
if(description == NULL){
player->position = NULL;
} else {
player->position = malloc(strlen(description) + 1);
strcpy(player->position, description);
player->id = id;
}
return player;
}
void destroy_player(Player *player){
if (player == NULL){
return;
} else {
free(player->position);
free(player);
}
}
void create_team(Club *team){
team->size = 0;
}
void print_club(const Club *club) {
int i = 0;
if (club == NULL) {
return;
} else if (club->size == 0) {
printf("No team members\n");
} else {
for (i = 0; i < club->size; i++) {
printf("Id: %d Position: %s\n", club->team[i]->id,
club->team[i]->position);
}
}
}
void add_player_to_club(Club *club, int id, const char *position){
if (club == NULL || club->size >= SIZE) {
return;
} else {
club->team[club->size] = create_player(id, position);
club->size++;
}
}
void destroy_club(Club *club){
int i = 0;
if (club == NULL) {
return;
} else {
club->size = 0;
for (i = 0; i < club->size; i++) {
destroy_player(club->team[i]);
}
}
}
I think the problem might be with my "destroy club" method. Player "objects" are stored in the "team" array. I allocated memory for each player object and deallocating by iterating through team array and freeing each index. What did I screw up?
In destroy_club, you set size to 0, then use that to loop through the players, so it loops through nothing.
Set size to 0 after cleaning up the players:
for (i = 0; i < club->size; i++) {
destroy_player(club->team[i]);
}
club->size = 0;
Related
When I try to implement parenthesis problem using stack (array representation) it showing above problem. Here I use dynamic memory allocation in array. When I try to compile the above program it appear built log like : process terminated with status -1073741510 (0 minute(s), 2 second(s))
#include<stdlib.h>
struct stack
{
int size;
int top;
char *arr;
};
int parenthematch(char *pt)
{
struct stack *st;
st->size = 100;
st->top = -1;
st->arr = (char *)malloc(st->size * sizeof(char)); //create array of st->size
for(int i=0; pt[i]!='\0'; i++)
{
if(pt[i]=='(')
{
push(st,'(');
}
else if(pt[i]==')')
{
if(isEmpty(st))
{
return 0;
}
pop(st);
}
}
int main()
{
char *p ="(34)(4(5+6))";
if(parenthematch(p))
{
printf("parenthesis match \n");
}
else
{
printf("Not match");
}
return 0;
} ```
#include <stdio.h>
#include <stdlib.h>
struct stack
{
size_t size;
int top;
char *arr;
};
void push(struct stack *st, char ch)
{
st->top += 1;
st->arr[st->top] = ch;
}
int isEmpty(struct stack *st)
{
return st->top == -1;
}
void pop(struct stack *st)
{
st->top -= 1;
}
int parenthematch(char *pt)
{
struct stack *st = (struct stack *)malloc(sizeof(struct stack));
st->size = 100;
st->top = -1;
st->arr = (char *)malloc(st->size * sizeof(char)); //create array of st->size
for (int i = 0; pt[i] != '\0'; i++)
{
if (pt[i] == '(')
{
push(st, '(');
}
else if (pt[i] == ')')
{
if (isEmpty(st) || st->arr[st->top] != '(')
{
return 0;
}
pop(st);
}
}
return isEmpty(st);
}
int main()
{
char p[] = "(34)(4(5+6))";
if (parenthematch(p))
{
printf("parenthesis match \n");
}
else
{
printf("Not match");
}
return 0;
}
i am writing a Generic ADT using C and i keep getting a segmentation fault when i free an element
PairResult pairClear(Pair pair)
{
if(pair == NULL)
{
return PAIR_NULL_ARGUMENT;
}
KeyElement key=pair->key;
DataElement data=pair->data;
if(key)
pair->free_key(key);//i get the Error here
if(data)
pair->free_data(data);
return PAIR_SUCCESS;
}
the memory for key and data is allocated :
Pair pairCreate( KeyElement key, DataElement data,
copyDataElements copy_data,
freeDataElements free_data,
copyKeyElements copy_key,
freeKeyElements free_key)
{
Pair pair = malloc(sizeof(*pair));
if(pair == NULL)
{
return NULL;
}
pair->copy_data=copy_data;
pair->copy_key=copy_key;
pair->free_data=free_data;
pair->free_data=free_key;
KeyElement new_string_key = copy_key(key);
DataElement new_string_data = copy_data(data);
if((new_string_key == NULL) || (new_string_data == NULL))
{
pairDestroy(pair);
return NULL;
}
pair->key = new_string_key;
pair->data = new_string_data;
return pair;
}
this pairDestroy
void pairDestroy(Pair pair)
{
if(pair == NULL)
{
return;
}
#ifndef NDEBUG
PairResult result =
#endif
pairClear(pair);
assert(result == PAIR_SUCCESS);
free(pair);
}
these are the copy functions used:
static KeyElement copyKeyInt(KeyElement n) {
if (!n) {
return NULL;
}
int *copy = malloc(sizeof(*copy));
if (!copy) {
return NULL;
}
*copy = *(int *) n;
return copy;
}
static DataElement copyDataChar(DataElement n) {
if (!n) {
return NULL;
}
char *copy = malloc(sizeof(*copy));
if (!copy) {
return NULL;
}
*copy = *(char *) n;
return (DataElement) copy;
}
and these are the free functions used
static void freeInt(KeyElement n) {
free(n);
}
static void freeChar(DataElement n) {
free(n);
}
and here is the struct of pair
struct Pair_t {
KeyElement key;
DataElement data;
copyDataElements copy_data;
freeDataElements free_data;
copyKeyElements copy_key;
freeKeyElements free_key;
};
these are all the typedef used :
typedef struct Pair_t* Pair;
typedef enum PairResult_t {
PAIR_SUCCESS,
PAIR_OUT_OF_MEMORY,
PAIR_NULL_ARGUMENT,
} PairResult;
typedef void *DataElement;
typedef void *KeyElement;
typedef DataElement(*copyDataElements)(DataElement);
typedef KeyElement(*copyKeyElements)(KeyElement);
typedef void(*freeDataElements)(DataElement);
typedef void(*freeKeyElements)(KeyElement);
and a main function so that u could reproduce it
int main()
{
Pair pair;
for (int i = 1; i < 1000; ++i) {
char j = (char) i;
++j;
pair=pairCreate(&i,&j,copyDataChar,freeChar,copyKeyInt,freeInt);
pairDestroy(pair);
}
I added everything I could for a reproducible code
if anything should be edited please tell me in the comments
Pair pairCreate(...) {
...
pair->free_data = free_data;
pair->free_data = free_key;
// ^^^^^^^^^ UH OH
...
You owe me 15 mins of debugging time.
So i know this might be asking too much but in my program i used valgrind for some reason it always says that i have 9 allocs mad and 1 free made, but in my code i freed all of the arrays i used, so i dont know are the allocs not being freed.
So if anyone could help me i would appreciate it a lot because im not understanding whats wrong in my code.
Program:
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024 /* max characters of a word */
#define MAX_SIZE 5
static int line = 1; /* counts the number of lines of the stdin */
int ident = 0; /*counts 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*/
char **sistema_eq;
typedef struct
{
int id;
char equipas[2][1024];
int pont[2];
char nome[MAX_CHARS];
} jogo;
typedef struct
{
int id;
char nome[MAX_CHARS];
int vit;
} vitorias;
/*-----------------------------------------*/
jogo *conj_jogos;
vitorias *conj_vit;
void a(char nome_jg[],char team1[],char team2[],int score1,int score2);
void A(char nome[]);
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));
conj_vit = (vitorias*)calloc(MAX_SIZE,sizeof(vitorias));
sistema_eq = (char**)calloc(MAX_SIZE,sizeof(*sistema_eq));
for(i=0;i<MAX_SIZE;i++)
{
sistema_eq[i] = (char*)calloc(1024,sizeof(char));
}
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);
for(i=0;i<size_until;i++) free(sistema_eq[i]);
free(sistema_eq);
return 0;
}
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++;
}
}
}
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++;
}
}
}
In the program below, I am allocating memory for pointer to pointer properly and then allocating individual pointers and setting values properly, even though I am getting the garbage value to one of the structure member. I don't understand where exactly I am going wrong.
The sample output of below program is:
***CK: H2 nSupport: 0
CK: H2 nSupport: 1303643608
CK: FR2 nSupport: 0
CK: H2 nSupport: 1303643608
CK: FR2 nSupport: 0
***CK: SP2 nSupport: 0
I don't understand how I am getting the value 1303643608, though it is set properly at the beginning.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NOK 15
#define ML 100
typedef struct sample_test_for_ties_t
{
char sender[NOK];
char receiver[NOK];
char message[ML];
}sample_test_for_ties;
typedef struct CUOfS_t{
char cK[NOK];
char eK[NOK];
char nK[NOK];
char AL[ML];
int nSupport;
}CUOfS;
CUOfS **Btenders = NULL;
sample_test_for_ties test_ties[] = {
{"H2","ICY", "fmaabghijklmmcdenoopqrstuvwxyz"},
{"FR2","AIY", "fmaabghijklmmcdenoopqrstuvwxyz"},
{"SP2","LAY", "fmaabghijklmmcdenoopqrstuvwxyz"},
{"H30","ICY", "fmaabghijklmmcdenoopqrstuvwxyz"},
{"F30","AIY", "fmaabghijklmmcdenoopqrstuvwxyz"},
{"W30","LAY", "fmaabghijklmmcdenoopqrstuvwxyz"},
};
void InitBtenders(int numOfBCtenders)
{
int count =0;
if(!Btenders)
{
if(Btenders = (CUOfS **)malloc(sizeof (**Btenders) * numOfBCtenders))
{
while(count < numOfBCtenders)
{
Btenders[count] = NULL;
count++;
}
}
else
{
printf("Malloc failed\n");
}
}
}
void freeBtenders(int numOfBCtenders)
{
int count =0;
if(Btenders)
{
while(count<numOfBCtenders)
{
if(Btenders[count]) {
free(Btenders[count]);
Btenders[count] = NULL;
}
count++;
}
free(Btenders);
Btenders = NULL;
}
}
void UpdateBtendersInfo(char *aContenders)
{
static int counter =0;
if(Btenders)
{
if(Btenders[counter] == NULL) {
Btenders[counter] = (CUOfS *)malloc(sizeof (Btenders[counter]));
if(Btenders[counter])
{
strcpy(Btenders[counter]->cK,aContenders);
strcpy(Btenders[counter]->eK,"\0");
strcpy(Btenders[counter]->nK,"\0");
memset(Btenders[counter]->AL,0,sizeof(Btenders[counter]->AL));
Btenders[counter]->nSupport = 0;
counter++;
}
else
{
printf("Insufficient memory for Btender\n");
}
}
}
else
{
printf("Looks like memory not allocated for Btenders\n");
}
int count =0;
while(count <counter && Btenders[count])
{
printf("***CK: %s nSupport: %d\n",Btenders[count]->cK,Btenders[count]->nSupport);
count++;
}
printf("\n");
}
int main()
{
int numOfBCtenders = 3;
int noc =0;
InitBtenders(numOfBCtenders);
while(noc < numOfBCtenders)
{
UpdateBtendersInfo(test_ties[noc].sender);
noc++;
}
freeBtenders(numOfBCtenders);
return 0;
}
I expect
***CK: H2 nSupport: 0
But I am getting
***CK: H2 nSupport: 1303643608
The way you allocate memory for Btenders is incorrect.
Btenders = (CUOfS **)malloc(sizeof (**Btenders) * numOfBCtenders) // WRONG
sizeof (**Btenders) is the same as sizeof(CUOfS), but you need sizeof(CUOfS*) :
Btenders = (CUOfS **)malloc(sizeof (*Btenders) * numOfBCtenders) // FIXED
Similarly for :
Btenders[counter] = (CUOfS *)malloc(sizeof (Btenders[counter])); // WRONG
sizeof (Btenders[counter]) is the same as sizeof(CUOfS*), but you need sizeof(CUOfS) :
Btenders[counter] = (CUOfS *)malloc(sizeof (*(Btenders[counter]))); // FIXED
Getting errors such as
stats.c:28:36: error: ‘factoryStats’ has no member named ‘candyConsumed’ factoryStatsArray[producer_number].candyConsumed++;
What I want to be able to achieve is to create an array of structs, then access it's members. Is this the wrong way to do it?
Tried using -> but that shouldn't and don't work since I'm storing structs, not pointers to structs.
#include "stats.h"
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int factoryNumber = 0;
int candyProduced = 0;
int candyConsumed = 0;
double minDelay = 0;
double avgDelay = 0;
double maxDelay = 0;
} factoryStats;
factoryStats *factoryStatsArray;
int NUM_FACTORIES = 0;
void stats_init (int num_producers) {
factoryStatsArray = malloc(sizeof(factoryStats) * num_producers);
NUM_FACTORIES = num_producers;
}
void stats_cleanup (void) {
free(factoryStatsArray);
}
void stats_record_produced (int factory_number) {
factoryStatsArray[factory_number].candyProduced++;
}
void stats_record_consumed (int producer_number, double delay_in_ms) {
factoryStatsArray[producer_number].candyConsumed++;
if (factoryStatsArray[producer_number].minDelay == 0) {
factoryStatsArray[producer_number].minDelay = delay_in_ms;
} else {
if (factoryStatsArray[producer_number].minDelay > delay_in_ms) {
factoryStatsArray[producer_number].minDelay = delay_in_ms;
}
}
if (factoryStatsArray[producer_number].maxDelay == 0) {
factoryStatsArray[producer_number].maxDelay = delay_in_ms;
} else {
if (factoryStatsArray[producer_number].maxDelay < delay_in_ms) {
factoryStatsArray[producer_number].maxDelay = delay_in_ms;
}
}
factoryStatsArray[producer_number].avgDelay+= delay_in_ms;
}
void stats_display(void) {
printf("%8s%10s%10s10s10s10s\n", "Factory#", "#Made", "#Eaten", "Min Delay[ms]", "Avg Delay[ms]", "Max Delay[ms]");
for (int i = 0; i < NUM_FACTORIES; i++) {
printf("%8d%8d%8d%10.5f%10.5f%10.5f",
factoryStatsArray[i].factoryNumber, factoryStatsArray[i].candyProduced,
factoryStatsArray[i].candyConsumed, factoryStatsArray[i].minDelay,
factoryStatsArray[i].avgDelay/factoryStatsArray[i].candyConsumed,
factoryStatsArray[i].maxDelay);
}
}
structs cannot be initialized this way. Remove all those = 0 in typedef struct { ... } factoryStats;. Afterwards it compiles as in http://ideone.com/uMgDzE .