C Segfaults when trying to free memory that no longer needs to be used -
i working on circular buffer program in c. buffer has able expand , shrink depending on conditions checked each time buffer updated new quote (the buffer contains stock quotes). however, when try expand buffer , free old (smaller) buffer, "invalid next size" errors gilbc.
my expand function follows:
cbuf* expandbuffer(cbuf *cb_ptr){ int newsize; newsize = (cb_ptr->maxsize * 2) -1; cbuf *tempbuffer = malloc(sizeof(cbuf) + newsize * sizeof(quote)); tempbuffer ->maxsize = cb_ptr->maxsize * 2; tempbuffer ->start = cb_ptr->start; tempbuffer ->end = cb_ptr->end; tempbuffer ->freeslots = tempbuffer->maxsize - cb_ptr->maxsize; int x; int counter; counter = 0; for(x = cb_ptr->end; x < cb_ptr->maxsize; x ++){ tempbuffer->quotebuffer[counter].time = cb_ptr->quotebuffer[x].time; tempbuffer->quotebuffer[counter].rate = cb_ptr->quotebuffer[x].rate; counter ++; } int y; for(y = 0; y < cb_ptr->start; y ++){ tempbuffer->quotebuffer[counter].time = cb_ptr->quotebuffer[y].time; tempbuffer->quotebuffer[counter].rate = cb_ptr->quotebuffer[y].rate; counter++; } tempbuffer->start = cb_ptr->maxsize; tempbuffer->end = 0; free(cb_ptr); return tempbuffer; }
and update function follows:
void cbuf_update(cbuf *cb_ptr, unsigned int time, double rate){ *code* if(cb_ptr->freeslots == 0){ printf("\n\nexpanding circular buffer!\n\n"); *cb_ptr = *(expandbuffer(cb_ptr)); } *more code here edited out since doesnt pertain question. }
and main:
int main(){ cbuf *cb1 ; cb1 = cbuf_init() ; cbuf_update(cb1, 60, 1.291) ; cbuf_update(cb1, 63, 1.287) ; cbuf_update(cb1, 63, 1.231) ; cbuf_update(cb1, 69, 1.229) ; cbuf_update(cb1, 72, 1.247) ; cbuf_update(cb1,361,1.291); cbuf_update(cb1, 411, 1.291) ; cbuf_update(cb1, 412, 1.281) ; cbuf_update(cb1, 413, 1.292) ; cbuf_update(cb1, 414, 1.284) ; cbuf_update(cb1, 414, 1.290) ; cbuf_update(cb1, 511, 1.241) ; cbuf_update(cb1, 512, 1.251) ; cbuf_update(cb1, 513, 1.232) ; cbuf_update(cb1, 514, 1.202) ; cbuf_update(cb1, 517, 1.119) ; cbuf_update(cb1, 551, 1.080) ; cbuf_update(cb1, 552, 1.081) ; cbuf_update(cb1, 553, 1.079) ; cbuf_update(cb1, 554, 1.088) ; cbuf_update(cb1, 561, 1.072) ; cbuf_update(cb1, 562, 1.113) ; cbuf_update(cb1, 563, 1.091) ; cbuf_update(cb1, 564, 1.092) ; cbuf_update(cb1, 571, 1.089) ; cbuf_update(cb1, 572, 1.073) ; cbuf_update(cb1, 573, 1.061) ; cbuf_update(cb1, 574, 1.111) ; cbuf_update(cb1, 581, 1.119) ; cbuf_update(cb1, 582, 1.123) ; cbuf_update(cb1, 583, 1.151) ; return 0; }
this segfaults @ line:
cbuf *tempbuffer = malloc(sizeof(cbuf) + newsize * sizeof(quote));
in expandbuffer after has expanded once successfully. if need expand buffer more once, segfault on line.
however, if comment out:
free(cb_ptr);
i no longer segfaults. however, cb_ptr (the "old" buffer being replaced new, larger buffer) must freed since no longer in use. confused why freeing , returning new, larger buffer cb_ptr in cbuf_update cause segfaults.
the problem this:
*cb_ptr = *(expandbuffer(cb_ptr));
in expandbuffer
free pointer, dereference free'd pointer in assignment. causes undefined behavior, can (and in case definitely) lead crash.
i suggest instead pass pointer reference (i.e. pointer pointer) cbuf_update
function:
void cbuf_update(cbuf **cb_ptr, unsigned int time, double rate) { /* ... */ if((*cb_ptr)->freeslots == 0) { printf("\n\nexpanding circular buffer!\n\n"); *cb_ptr = expandbuffer(*cb_ptr); } /* ... */ }
call new function address-of operator pointer:
cbuf_update(&cb1, 60, 1.291) ;
Comments
Post a Comment