私はこれについて何時間も頭を悩ませてきました。XCode 5 で Mac OS X 10.8 を実行しています。次のエラーが表示されます。
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
残念ながら、object 0x1006487b8
はこの時点で解放されており、私のデバッガーにはそこにあったものは記憶されていません。
問題は、エラーが同じ場所で発生しないことです。少しのメモリが適切に解放されておらず、コンピュータがそれを別の目的に使用しようとして混乱してしまうとしか思えません。
私のコードは SDL 2 を使用しており、私が知る限りfree
、次のような形式の関数呼び出しのみが発生します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
ゲートの配列への静的なファイル スコープ ポインターであり、ファイルの先頭でそのように宣言されます。
static LGC_Gate* gates = NULL;
numgates
ファイルの先頭でゼロに初期化され、現在使用中のゲート数を表します。gates
サイズは常に である必要がありますnumgates * sizeof(LGC_Gate)
。
私の計画は、ユーザーが作成したすべてのゲートを単一の配列に保持することでした。これにより、簡単にそれらを集計して、すぐに取得できるようになりました。このLGC_CreateEmptyGate
関数は、たとえば次のように使用されます。
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;
}
私はひどく間違ったことをしましたか?
アップデート
次のコードを使用してデバッグを行いました。
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.
}
}
}
驚いたことに、これは実際にはエラーを出力し、実際にいくつかのポインターでクラッシュします。訂正: エラー ポインターは常に 3 番目のポインターのようです。LGC_InitActGate
一度呼び出すLGC_InitEmptyGate
と、残りの期間は単にデータをコピーすることに注意してください。何が起こっている?
更新 2
さて、私は今エラーを発見したと思います。realloc が呼び出されるたびに、メモリのブロック全体が再配置される場合と再配置されない場合があります。これにより、以前の解放されたメモリを指している無用の 5 つのポインターの配列がレンダリングされます。これは完全に理にかなっていますが、これは 1 つのとんでもないバグです。前に気づいていたはずです。これを修正する方法はわかりませんが、助けてくれてありがとう。