I've got a strange problem with realloc, here's my code (relevant parts only, too big to post the full code here):
char * print_bar(struct bar *ptr) {
char *buf = NULL;
char *buftmp = NULL;
size_t size = 60;
int count = 0;
if (ptr) {
while (count == 0 || count+4 >= size) {
buftmp = (char *) realloc((void *) buf, size * sizeof (char));
if (buftmp == NULL) {
if (buf != NULL) free(buf);
exit(EXIT_FAILURE);
}
buf = buftmp;
count = snprintf(buf, size, "%04d-%02d-%02d\t%02d:%02d:00\t%d\t%.2f\t%.2f\t%.2f\t%.2f\t%d",
ptr->year,
ptr->month,
ptr->day,
ptr->hour,
ptr->minute,
ptr->timeframe,
ptr->open,
ptr->high,
ptr->low,
ptr->close,
ptr->volume
);
size += 4;
}
}
return buf;
}
char * print_historico(short timeframe) {
struct barlist *tmp = get_barlist(timeframe);
struct bar *ptr;
char * result = NULL;
char * resulttmp = NULL;
char * buf;
int len;
if (tmp) {
ptr = tmp->first;
while (ptr) {
buf = print_bar(ptr);
len = (result != NULL) ? strlen(result)+strlen(buf)+1 : strlen(buf)+1;
resulttmp = (char *)realloc((void *)result, len);
if (resulttmp == NULL)
{
if (result != NULL) free(result);
exit (EXIT_FAILURE);
}
result = resulttmp;
strncat(result, buf, strlen(buf));
free(buf);
ptr = ptr->next;
}
}
return result;
}
In my main function i've got the following loop:
for (i = 1; i <= 27; i++) {
historico = print_historico(i);
if (historico != NULL)
{
puts(historico);
free(historico);
}
}
If i compile and run it fails with "realloc(): invalid next size: 0x0000000001704f60". If i run with the debugger i see it finishes the first iteration of the main loop ok, freeing the 'historico' variable. When it executes "print_historico" with i=2 it fails on the second iteration of the "while(ptr)" loop.
I can't find a reason, any clue? I've also tried to make a small program to isolate the problem, but i wasn't able.
strncat(result, buf, strlen(buf));
This is a problem. (It might be the cause of the problem you are reporting having.)
When the first realloc occurs, the result is not initialized. You really need to put a '\0' in the first char position for the strncat to work (reliably).
resulttmp = (char *)realloc((void *)result, len);
if (resulttmp == NULL)
{
if (result != NULL) free(result);
exit (EXIT_FAILURE);
}
if(result == NULL) *resulttmp = '\0' // YOU NEED THIS!! First time initialization.