簡體   English   中英

什么是 glibc free/malloc/realloc invalid next size/invalid pointer 錯誤以及如何解決?

[英]What is a glibc free/malloc/realloc invalid next size/invalid pointer error and how to fix it?

您很可能會看到此問題,因為您的問題已作為此問題的副本關閉。 有關相關問題的完整列表,請參閱A long list of possible duplicates — C memory allocation and overrunning bounds on Meta Stack Overflow。


示例問題

來自免費字符 *: noobie在 2014 年 4 月 11 日提出的下一個尺寸無效(快速)。

我在連接過程后釋放了一個char* ,但我收到了這個錯誤:

free(): invalid next size (fast): 0x0000000001b86170

這是我的代碼:

void concat(stringList *list) {
    char *res = (char*)malloc(sizeof(char*));

    strcpy(res, list->head->string);

    list->tmp = list->head->next;
    while (list->tmp != NULL) {
        strcat(res, ",");
        strcat(res, list->tmp->string);
        list->tmp = list->tmp->next;
    }

    printf("%s\n", res);
    free(res);
}

一般問題

運行我的程序時,我看到如下錯誤消息:

*** glibc detected *** ./a.out: free(): corrupted unsorted chunks: 0x12345678 ***

詳細信息可以在*** glibc detected ***和程序名稱之后包含以下任何內容,並且該消息后跟一個十六進制地址(顯示為 0x12345678)和另一個***

  • free(): corrupted unsorted chunks: 0x12345678
  • free(): invalid next size (fast): 0x12345678
  • free(): invalid next size (normal): 0x12345678
  • free(): invalid pointer: 0x12345678
  • free(): invalid size: 0x12345678
  • malloc(): corrupted unsorted chunks: 0x12345678
  • malloc(): corrupted unsorted chunks 2: 0x12345678
  • malloc(): memory corruption: 0x12345678
  • malloc(): memory corruption (fast): 0x12345678
  • malloc(): smallbin double linked list corrupted: 0x12345678
  • munmap_chunk(): invalid pointer: 0x12345678
  • realloc(): invalid next size (fast): 0x12345678
  • realloc(): invalid old size (fast): 0x12345678
  • realloc(): invalid pointer: 0x12345678
  • corrupted double-linked list: 0x12345678

這發生在調用frobnicate()函數時; 該功能有什么問題?

回答示例問題

unwind給出了示例問題的公認答案

你的代碼是錯誤的。

您正在為單個指針( malloc(sizeof(char*)) )分配空間,但沒有字符。 您正在用所有字符串覆蓋分配的空間,導致未定義的行為(在這種特殊情況下,破壞了malloc()的簿記數據)。

您不需要為指針( res )分配空間; 它是一個局部變量。 必須為要存儲在指針所持有的地址的所有字符分配空間。

由於您將遍歷列表以查找要連接的字符串,因此您無法預先知道總大小。 您將不得不對列表進行兩次遍歷:一次對每個字符串的strlen()求和,然后為分隔符和終止符分配該加空間,然后在實際進行連接時再進行一次遍歷。

通用答案

您看到的是 glibc 分配器內部結構損壞的結果。 當您分配或釋放動態內存時,分配器必須管理它從操作系統保留的內存,並根據您請求的操作,找到一個新的塊來分發,將一個釋放的塊排序到它的列表中可以稍后再分發,或者將內存還給操作系統。 這些錯誤消息表明它用於管理此功能的數據結構已損壞。

這些錯誤都意味着你的一些代碼修改了它沒有被使用的內存,調用了未定義的行為 這很可能是在您的程序中較早地覆蓋了一些內存的結果,並且完全有可能錯誤不在frobnicate()函數中。

是的,這意味着錯誤可能出現在您的程序或您使用的 3rd 方庫中的任何位置

對於 Stack Overflow 來說,這可能不是一個好問題。 除非您能很好地簡單地重現您的問題,否則這個社區可能無法為您提供太多幫助。 錯誤的原因可能在您的代碼中的任何地方(並且通常不在發現錯誤的函數中),並且可能在我們看不到的代碼中。 Stack Overflow不是一個協作調試站點。 即使有人可以發現您的代碼中的缺陷,您的具體問題也不可能對任何未來的訪問者有所幫助。

常見原因

  • 免費后使用。 您已經釋放/刪除了一些內存並隨后寫入其中,覆蓋了 glibc 記賬所需的結構。
  • N 誤差。 您正在將分配的塊之后的 N 個字節寫入 glibc 內部用於其簿記的未分配內存。
  • 未初始化的指針。 您沒有初始化指針。 巧合的是,它指向 glibc 保留但未由您的程序分配的一些內存,您寫入它。
  • 分配錯誤的空間量。 這可能是因為您寫了long *data = malloc(number * 4)而不是long *data = malloc(number * sizeof(long)); 或(更好) long *data = malloc(number * sizeof(*data)); . 還有許多其他方法可以使尺寸計算錯誤。 另一種常見的情況是忘記考慮字符串末尾的空終止符: char *copy = malloc(strlen(str)); 而不是char *copy = malloc(strlen(str)+1); .

你現在需要做的就是卷起袖子調試那個問題

沒有簡單的答案要尋找什么或要修復什么。 您沒有使用錯誤的單個語法結構。 這個錯誤的原因可能有數千種。

工具

  • valgrind一個工具,主要是為了准確地發現這類錯誤。 如果它找不到任何東西,請確保您使用的是最新版本,並且您也在嘗試包含的exp-sgcheck工具。 如果您正在運行多線程代碼,則原因也可能與競爭條件有關,因此您可能想嘗試包含的競爭條件檢查器drdhelgrind以獲得更多信息。 在撰寫本文時,valgrind 支持以下平台:
    • X86/Linux,
    • AMD64/Linux,
    • ARM/Linux,
    • PPC32/Linux,
    • PPC64/Linux,
    • S390X/Linux,
    • MIPS32/Linux,
    • MIPS64/Linux,
    • ARM/Android(2.3.x 及更高版本),
    • X86/Android(4.0 及更高版本),
    • X86/達爾文和
    • AMD64/Darwin(Mac OS X 10.7,對 10.8 的支持有限)。
  • purify與 valgrind 類似的工具,但商業化並針對不同的平台集。
  • AddressSanitizer一個類似的工具,但集成到編譯器工具鏈(gcc 和 clang)中。
  • efence分配器替換的下降,它將嘗試更早地使您的程序崩潰,以便您可以使用正常的調試器找出寫入無效內存的位置。
  • dmalloc一個與 efence 目的相似的庫。

需要更多幫助

如果您無法使用這些工具解決您的問題,您應該嘗試創建一個 MCVE(如何創建一個最小、完整和可驗證的示例? ),或者等效地,一個 SSCCE(簡短、自包含、正確(可編譯) ,例)。

請記住處理您的代碼副本,因為創建 MCVE 需要您無情地刪除無助於重現問題的代碼。 使用 VCS(版本控制系統)來協助是個好主意; 您可以記錄將問題減少到最低限度的中間階段。 它可能是一個新的一次性存儲庫,僅用於將您的問題減少到可管理的大小。

通過對代碼進行良好的模塊化設計,創建 MCVE 應該相對容易。 也許您也已經有了一個更適合輸入上述工具之一的單元測試。 您也可能只想創建一個以后可以用作此錯誤的回歸測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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