C: copying some structs causes strange behavior
- by Jenny B
I have an annoying bug in the line
rq->tickets[rq->usedContracts] = toAdd;
if i do: rq->tickets[0] = toAdd the program crashes
if i do rq->tickets[1] = toAdd; it works
valgrind says
==19501== Use of uninitialised value of size 8
and
==19501== Invalid write of size 8
for this very line. What is wrong?
struct TS_element {
int travels;
int originalTravels;
int cost;
char** dates;
int moneyLeft;
} TicketSet;
struct RQ_element {
int usedContracts;
struct TS_element* tickets;
} RabQav;
TicketSetStatus tsCreate(TicketSet* t, int n, int c) {
if (n <= 0)
return TS_ILLEGAL_PARAMETER;
TicketSet* myTicketSet = (TicketSet*) malloc(sizeof(TicketSet));
if (myTicketSet == NULL) {
return TS_CANNOT_CREATE;
}
myTicketSet->usedTravels = 0;
myTicketSet->originalTravels = n;
myTicketSet->cost = c;
myTicketSet->moneyLeft = n * c;
char** dates = malloc(sizeof(char**)* (n)); //todo maybe c99 allows dynamic arrays?
for (int i = 0; i < n; i++) {
dates[i] = malloc(sizeof(char)*GOOD_LENGTH+1);
if (dates[i] == NULL) {
free(dates);
free(t);
return TS_CANNOT_CREATE;
}
}
myTicketSet->dates = dates;
*t = *myTicketSet;
return TS_SUCCESS;
}
static void copyTicketSets(TicketSet* dest, const TicketSet* source) {
dest->usedTravels = source->usedTravels;
dest->originalTravels = source->originalTravels;
dest->cost = source->cost;
dest->moneyLeft = source->moneyLeft;
for (int i = 0; i < source->originalTravels; i++) {
if (NULL != source->dates[i]) {
free(dest->dates[i]);
dest->dates[i] = malloc(sizeof(char) * GOOD_LENGTH + 1);
if (dest->dates[i] == NULL) {
free(dest->dates); //todo free dates 0...i-1
free(dest);
return;
}
strcpy(dest->dates[i], source->dates[i]);
}
}
}
RabQavStatus rqLoadTS(RabQav* rq, TicketSet t, DateTime dt) {
TicketSet toAdd;
TicketSetStatus res = tsCreate(&toAdd, t.originalTravels, t.cost);
if (res != TS_SUCCESS) {
return RQ_FAIL;
}
copyTicketSets(&toAdd, &t);
rq->tickets[rq->usedContracts] = toAdd;
rq->usedContracts++;
return RQ_SUCCESS;
}