I've been scratching my head over this for hours. I'm running Mac OS X 10.8, with XCode 5. I've been getting the following error:
malloc: *** error for object 0x1006487b8: incorrect checksum for freed object - object was
probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Unfortunately, object 0x1006487b8
is freed at this point, and my debugger has no recollection of what was there.
The problem is, the error never occurs in the same place. I can only assume that a bit of memory isn't freed properly, and then the computer tries to use it for some other purpose and winds up confused.
My code is using SDL 2, and as far as I can tell, the only free
-like function call occurs in the following form with a realloc
:
static LGC_Gate* LGC_CreateEmptyGate(){
if (!gates) {
gates = malloc(sizeof(LGC_Gate));
if (!gates)
return NULL;
}
else{
LGC_Gate* tmpgates = realloc(gates, sizeof(LGC_Gate) * (numgates + 1));
if (tmpgates)
gates = tmpgates;
else
return NULL;
}
numgates++;
gates[numgates - 1].id = numgates - 1;
return &(gates[numgates - 1]);
}
gates
is a static, file-scope pointer to an array of gates and is declared as such at the top of the file:
static LGC_Gate* gates = NULL;
numgates
is initialized to zero at the beginning of the file, and represents the number of gates currently in use. gates
should always be of size numgates * sizeof(LGC_Gate)
.
My plan was to hold all gates created by the user in a single array, so that it was easy to tally them and get each at a moment's notice. The LGC_CreateEmptyGate
function is used like this, for example:
LGC_Gate* LGC_InitActGate(LGC_Action act, uint8_t innum, uint8_t outnum){
LGC_Gate* product = LGC_CreateEmptyGate();
if (!product)
return NULL;
product->rule.type = LGC_FUNCTION;
product->rule.act = act;
product->input.used = innum;
product->input.val = 0;
product->output.used = outnum;
product->output.val = 0;
int i;
for (i = 0; i < 8; i++) {
product->inputfrom[i].active = 0;
}
return product;
}
Have I done something horribly wrong?
I have done some debugging with the following code:
printf("%d\n", sizeof(LGC_Gate));
LGC_Gate* TestGates[5];
//Go through the gates, initialize each of them, record the value of their ptr,
//and if any are LESS than sizeof(LGC_Gate) apart, report an error.
int gcount;
for (gcount = 0; gcount < 5; gcount++) {
TestGates[gcount] = LGC_InitActGate(LGC_NOR, 2, 1);
printf("%p\n", TestGates[gcount]);
if (gcount < 4) {
if (TestGates[gcount] + sizeof(LGC_Gate) > TestGates[gcount + 1]) {
printf("Error!");
//TestGates[gcount + 1]->id = 4; If this line were uncommented,
// BAD_ACCESS ensues.
}
}
}
To my complete surprise, this actually outputs an error, and indeed crashes on some of the pointers. CORRECTION: The erroring pointer always seems to be the third one. Note that LGC_InitActGate
calls LGC_InitEmptyGate
once, and simply copies data for the rest of its duration. What is going on?
Well, I believe I've discovered the error now. Every time realloc is called, the entire block of memory may or may not relocate, which renders the array of 5 pointers I had useless and pointing to old, freed memory. This makes total sense, but it's one heckuva bug. I should've noticed before. I'm not sure how to fix this, but thanks for the help I got.
Every time realloc
is called from main
, the memory block may or may not relocate, which leaves the array TestGates
have elements that point to invalid memory.