2011-05-10 54 views
1

我已經達到了realloc停止返回指針的地步 - 我假設數組沒有足夠的空間來擴展或移動。唯一的問題是我真的需要這種內存來存在或應用程序無法按預期運行,所以我決定嘗試malloc - 因爲realloc無法正常工作,所以期待它不起作用 - 但它確實如此。爲什麼?如何重新分配不工作,但malloc可以嗎?

然後我將指針數組memcpy分配到新分配的數組中,但發現它已破壞它,像0x10和0x2b這樣的指針被放入數組中。有真正的指針,但如果我用for循環替換memcpy,則修復它。爲什麼memcpy這樣做?我的代碼中不應該使用memcpy嗎?

代碼:

float * resizeArray_by(float *array, uint size) 
{ 
    float *tmpArray = NULL; 
    if (!array) 
    { 
     tmpArray = (float *)malloc(size); 
    } 
    else 
    { 
     tmpArray = (float *)realloc((void *)array, size); 
    } 

    if (!tmpArray) 
    { 
     tmpArray = (float *)malloc(size); 
     if (tmpArray) 
     { 
      //memcpy(tmpArray, array, size - 1); 
      for (int k = 0; k < size - 1; k++) 
      { 
       ((float**)tmpArray)[k] = ((float **)array)[k]; 
      } 
      free(array); 
     } 
    } 

    return tmpArray; 
} 

void incrementArray_andPosition(float **& array, uint &total, uint &position) 
{ 
    uint prevTotal = total; 
    float *tmpArray = NULL; 
    position++; 
    if (position >= total) 
    { 
     total = position; 
     float *tmpArray = resizeArray_by((float *)array, total); 
     if (tmpArray) 
     { 
      array = (float **)tmpArray; 

      array[position - 1] = NULL; 
     } 
     else 
     { 
      position--; 
      total = prevTotal; 
     } 
    } 
} 

void addArray_toArray_atPosition(float *add, uint size, float **& array, uint &total, uint &position) 
{ 
    uint prevPosition = position; 
    incrementArray_andPosition(array, total, position); 

    if (position != prevPosition) 
    { 
     float *tmpArray = NULL; 
     if (!array[position - 1] || mHasLengthChanged) 
     { 
      tmpArray = resizeArray_by(array[position - 1], size); 
     } 

     if (tmpArray) 
     { 
      memcpy(tmpArray, add, size); 
      array[position - 1] = tmpArray; 
     } 
    } 
} 

我所有修補程序後,代碼可能inits。這裏有趣的是,在對數組進行分類之後,我用malloc分配了一個巨大的數組,因此將這些數組重新排列成一個數組,以用作GL_ARRAY_BUFFER。如果realloc由於缺少空間而沒有分配,那麼爲什麼不分配?

最後,無論如何這最終導致它崩潰。一旦它崩潰後,通過渲染功能。如果我刪除了所有的修復程序,並在realloc未分配時捕獲它,則可以正常工作。這引發了這個問題,mallocing我的數組有什麼問題,而不是重新分配導致進一步下降的問題?

我的數組的指針是浮點指針。當我增長數組時,它被轉換爲一個指向浮點數並重新分配的指針。我在Android上構建,所以這就是爲什麼我認爲那裏缺乏內存。

+0

在看不到代碼的情況下很難理解問題所在。你能否包含一些關於你使用memcpy的內容?實際的realloc和malloc調用? – 2011-05-10 14:32:02

+0

聽起來像這裏工作的錯誤。無論是在你的代碼中,還是在CRT中(不太可能)。 – 2011-05-10 14:36:11

+0

你在混合'size'變量的含義嗎?它是以字節爲單位的數組大小還是數組中的浮點數? – James 2011-05-10 15:20:25

回答

1

你很困惑size和指針類型。在內存分配中,size是字節數,並且您正在將指針類型轉換爲float *,實際上會創建大小爲size/sizeof(float)float的數組。在memcpy相當的代碼中,您將數組視爲float **並將它們複製size。這會破壞堆,假設sizeof(float *) > 1,並且可能是後來問題的來源。此外,如果您要將100個大小的數組複製到200個大小的數組中,則需要複製100個以上的元素,而不是200個。 )會導致程序崩潰。

指向float的指針的動態分配數組將是float **類型,而不是float *,當然不是這兩者的混合。數組的大小是指向malloc和朋友的字節數,以及所有數組操作中的元素數。假設源塊和目標塊不重疊(並且分別分配的存儲塊不包含),則將忠實地複製字節。但是,當複製的數字應該是舊數組的確切字節大小時,您已指定size - 1複製的字節數。 (無論如何,你會得到錯誤的指針值?如果它在數組的擴展部分,那麼你就是在那裏複製垃圾。)如果memcpy給你胡說八道,這開始變得無稽之談了,而不是你的問題。

+0

當我輸出memcpy數組memcpy(tmpArray,array,size - 1)的值時,我得到了壞指針。 – NebulaFox 2011-05-10 17:11:02

3

從所有不同位的信息來看(realloc找不到內存,memcpy意外行爲,崩潰),這聽起來很像堆損壞。如果沒有一些你正在做的事情的代碼示例,很難說清楚,但是看起來你在某些時候錯誤地管理了內存,導致堆進入無效狀態。

您是否能夠在Linux等其他平臺上編譯代碼(您可能需要存儲一些特定於android的API)?如果是這樣,你可以看到該平臺上發生了什麼和/或使用valgrind來幫助追捕它。

最後,你有這個標記的C++爲什麼你使用malloc/realloc而不是,例如,vector(或另一個標準容器)或new

+2

+1爲「你爲什麼用C++編程C?」 – 2011-05-10 14:52:44

+0

在android-ndk上,標準庫不存在。我原本使用矢量。因爲在C++中沒有realloc,所以我使用C編寫。 – NebulaFox 2011-05-10 14:54:43

0

而且順便說一句,你不需要測試,如果arrayNULL

可以給出一個NULL指針,當像malloc通過

tmpArray = realloc(array, size*sizeof (float)); 

realloc行爲取代

if (!array) 
{ 
    tmpArray = (float *)malloc(size); 
} 
else 
{ 
    tmpArray = (float *)realloc((void *)array, size); 
} 

另一件事,小心大小不是0,因爲realloc與0大小是一樣的 free

第三點,做沒有typecast指針,當不是絕對必要的。你指定了分配函數的返回,自ANSI-C以來它被認爲是不好的做法。這在C++中是必須的,但是當你使用C分配時,你顯然不是使用C++的(在這種情況下,你應該使用new/delete)。 將數組轉換爲(void *)也是不必要的,因爲如果您的參數被錯誤地聲明(它可能是一個int或一個指向指針的指針,並且通過強制你將會禁止該警告),它可能會隱藏一些警告。

相關問題