[英]Malloc Error Caused by Realloc
我已經為此努力了好幾個小時。 我正在運行帶有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
是指向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.
}
}
}
令我完全驚訝的是,這實際上輸出了一個錯誤,並且確實在某些指針上崩潰了。 更正:錯誤的指針始終似乎是第三個指針。 請注意, LGC_InitActGate
調用一次LGC_InitEmptyGate
,並在剩余LGC_InitEmptyGate
簡單地復制數據。 到底是怎么回事?
好吧,我相信我現在已經發現了錯誤。 每次調用realloc時,整個內存塊可能會或可能不會重定位,這使我擁有的5個指針數組無效,並指向舊的,已釋放的內存。 完全有道理,但這只是一個heckuva錯誤。 我之前應該注意到。 我不確定如何解決此問題,但感謝您的幫助。
該錯誤告訴您,系統將嘗試分配一些內存,但是當它進入其空閑池時,下一個可用塊似乎已損壞。
void* p = malloc(100);
free(p);
strcpy(p, "How do you like these apples, malloc?";
p = malloc(100); // <-- crash may happen here, depending on how the free list works.
通常情況下,碰撞的位置只是檢測而已,而不是原因。
有時您可以像這樣查找崩潰的一種方法是查看地址上的數據(很幸運,並且可以識別字符串或眾所周知的值)。
否則,是時候打破valgrind了。
每次從main
調用realloc
,內存塊可能會或可能不會重定位,這會使數組TestGates
擁有指向無效內存的元素。
該代碼對我來說看起來不錯,盡管可以簡化代碼,因為您實際上不需要特殊化啟動條件。 [注1]
您確定您沒有堅持使用代碼中某個“門”的指針嗎? 您必須非常小心自動重新分配向量,尤其是可能在函數中修改的全局向量:
LGC_Gate* product = LGC_CreateEmptyGate();
some_innocuous_looking_function(); // Oops, this function calls CreateEmptyGate
product->output.val = some_value;
注1:根據Posix realloc規范 :
如果ptr是一個空指針,則對於指定的大小,realloc()將等效於malloc()。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.