簡體   English   中英

重新分配引起的Malloc錯誤

[英]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簡單地復制數據。 到底是怎么回事?

更新2

好吧,我相信我現在已經發現了錯誤。 每次調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM