2010-06-07 128 views
54

我正在實施一個分而治之的多項式算法,所以我可以將它與OpenCL實現進行基準測試,但是我無法獲得malloc的工作。當我運行程序時,它會分配一堆東西,檢查一些東西,然後將size/2發送給算法。然後,當我再次命中malloc線就吐出了這一點:爲什麼我得到一個C malloc斷言失敗?

malloc.c:3096:SYSMALLOC:斷言`(old_top ==(((mbinptr)(((字符*)&((AV) - > bins [((1) - 1)* 2]))__builtin_offsetof(struct malloc_chunk,fd))))& & old_size == 0)|| ((unsigned long)(old_size)> =(unsigned long)((((_builtin_offsetof(struct malloc_chunk,fd_nextsize))+((2 *(sizeof(size_t)))-1)&〜((2 * (爲size_t))) - 1)))& &((old_top) - >大小爲0x1 &)& &((無符號長整數)OLD_END & pagemask)== 0)」失敗。 中止

所討論的行是:

int *mult(int size, int *a, int *b) { 
    int *out,i, j, *tmp1, *tmp2, *tmp3, *tmpa1, *tmpa2, *tmpb1, *tmpb2,d, *res1, *res2; 
    fprintf(stdout, "size: %d\n", size); 

    out = (int *)malloc(sizeof(int) * size * 2); 
} 

我檢查尺寸與fprintf,並且它是一個正整數(通常爲50在該點處)。我試着用普通電話號碼撥打malloc,我仍然遇到了錯誤。我只是不知道發生了什麼,而迄今爲止我發現的任何Google都沒有什麼幫助。

任何想法發生了什麼?我試圖弄清楚如何編譯一個新的GCC以防萬一它是編譯器錯誤,但我真的懷疑它。

+0

我懷疑問題實際上是一個線路之前。也許雙免費?在程序 – 2010-06-07 05:21:10

+0

第三行: INT * MULT(INT大小,INT *一個,INT * B) { \t INT *總分,I,J,* TMP1,* TMP2,* TMP3,* tmpa1 ,* tmpa2,* tmpb1,* tmpb2,d,* res1,* res2; \t fprintf(stdout,「size:%d \ n」,size); \t \t out =(int *)malloc(sizeof(int)* size * 2); – Chris 2010-06-07 05:22:33

回答

65

99.9%的可能是你已經損壞的內存(過高或過低流動的緩衝區,寫信給在被釋放後的指針,所謂的自由對同一指針兩次等)

下運行代碼Valgrind查看你的程序在哪裏做了不正確的事情。

+1

已修復。 Valgrind明確幫助。我抄錄了舊的matlab代碼,並且有一個迭代了j的for循環,然後在它內部做了j ++,它覆蓋了它正在寫入的數組,並以某種方式導致malloc失敗。 感謝您的幫助! – Chris 2010-06-07 05:52:15

+0

Valgrind只是我需要弄清楚當我發生這個錯誤時發生了什麼的工具。謝謝你提到它。 – alexwells 2012-12-31 18:05:55

+1

我乾淨的構建,它正常工作。 – 2015-10-19 03:50:28

1

因爲我們忘記用的sizeof(int)的繁殖我們得到了這個錯誤。注意malloc(..)的參數是一些字節數,而不是機器字的數量或其他。

0

我是從移植的Visual C一個應用程序與gcc在Linux和我有

malloc.c同樣的問題:3096:SYSMALLOC:使用gcc斷言在Ubuntu 11

我將相同的代碼移到Suse發行版(在其他計算機上),我沒有任何問題。

我懷疑問題不在我們的程序中,而是在自己的libc中。

40

爲了讓您更好地瞭解爲什麼發生這種情況,我想對@ r-samuel-klatchko的答案進行一些說明。

當你打電話給malloc時,真正發生的事情比給你一大塊內存來玩更復雜一點。在引擎蓋下,malloc還會保留一些關於它給予您的內存的內務處理信息(最重要的是,它的大小),以便當您撥打free時,它知道需要釋放多少內存。此信息通常在malloc返回給您的內存位置之前保留。更詳盡的信息可以發現on the internet™,但(非常)基本思路是這樣的:

+------+-------------------------------------------------+ 
+ size |     malloc'd memory    + 
+------+-------------------------------------------------+ 
     ^-- location in pointer returned by malloc 

大廈這個(大大簡化了的東西),當你調用malloc,它需要得到一個指針下一部分內存可用。這樣做的一個非常簡單的方法是查看它給出的前一位內存,並將size字節向下(或向上)移動到內存中。有了這個實現,你結束了你的記憶看起來像這樣分配p1p2p3後:

+------+----------------+------+--------------------+------+----------+ 
+ size |    | size |     | size |   + 
+------+----------------+------+--------------------+------+----------+ 
     ^- p1     ^- p2      ^- p3 

那麼,是什麼原因造成的錯誤?假設你的代碼錯誤地寫了你已經分配的內存量(或者是因爲你分配的內存少於你需要的數量,或者是因爲你在代碼中某處使用了錯誤的邊界條件)。假設您的代碼將如此多的數據寫入p2,它將開始覆蓋p3size字段中的內容。當你現在接下來調用malloc時,它會查看它返回的最後一個內存位置,查看它的大小字段,移動到p3 + size,然後開始從那裏分配內存。由於您的代碼已被覆蓋size,但是,此內存位置不再位於先前分配的內存之後。

不用說,這可以破壞浩劫!因此,malloc的實現者已經進行了大量的「斷言」或檢查,試圖做一系列的理智檢查,以便在發生這種情況時(以及其他問題)進行檢查。在你的特定情況下,這些斷言被違反,並因此中斷,告訴你,你的代碼即將做一些它不應該做的事情。

如前所述,這是一個過分簡單化,但它足以說明這一點。 malloc的glibc實現超過5k行,並且已經對如何構建良好的動態內存分配機制進行了大量研究,因此不可能在SO答案中包含它。希望這給了你一些關於究竟是什麼導致問題的看法!

+0

這應該是被接受的答案.. – 2017-09-28 08:12:50

1

我得到了以下信息,類似於你的一個:

 

    program: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed. 

犯了錯誤之前的一些方法調用,使用malloc時。在更新sizeof()後的因子時,錯誤地用'+'覆蓋乘號'*' - 運算符將字段添加到無符號字符數組中。

這裏是負責在我的情況下錯誤的代碼:

 

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)+5); 
    b[INTBITS]=(some calculation); 
    b[BUFSPC]=(some calculation); 
    b[BUFOVR]=(some calculation); 
    b[BUFMEM]=(some calculation); 
    b[MATCHBITS]=(some calculation); 

在另一種方法後,我再次使用malloc和它產生以上所示的錯誤消息。該電話是(很簡單):

 

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)*50); 

使用「+」思考 - 關於第一個呼叫,從而導致誤演算與陣列的直接初始化合並後,這不是(覆蓋內存標誌分配給數組),給malloc的內存映射帶來了一些混淆。因此第二個電話出錯了。

0

我得到了同樣的問題,我用malloc重新n在循環中添加新的char *字符串數據。我面臨同樣的問題,但釋放後分配內存void free()問題進行排序