2009-11-19 60 views
3

我正在用C編寫一個使用win32 API的應用程序。 當我嘗試放大我的數組的大小時,使用HeapRealloc()函數,它會更改數組中的當前值,而不是複製它們。 我使用的代碼重新分配內存:爲什麼Win32 HeapReAlloc()更改值?

BOOL ChangeFeedArraySize(UINT newSize) 
{ 
    char tempChar[20] = ""; 
    PFEED tempArr; 
    if (newSize == 1) 
    { 
     tempArr = (PFEED)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(FEED)); 
    } 
    else 
    { 
     tempArr = (PFEED)HeapReAlloc(heap, HEAP_ZERO_MEMORY, categoryArray, newSize * sizeof(FEED)); 
     // FEED - a struct 
     // PFEED - a pointer to the struct 
     // categoryArray - array to be reallocated 
    } 

    if (tempArr != NULL) 
    { 
     MessageBox(NULL, ltoa(HeapSize(heap, 0, tempArr),tempChar,10) , "Heap size after reallocation", MB_OK | MB_ICONEXCLAMATION); 
     feedArray = tempArr; 
     return TRUE; 
    } 
    else 
    { 
     return FALSE; 
    } 
} 

這裏是陣列的狀態,在斷點時。 饋送數組顯示當前數組狀態。 temp數組顯示新的重新分配的數組狀態(這是不同的)。

飼料數組:

feedArray http://www.freeimagehosting.net/uploads/526b0b2172.jpg

臨時數組:

tempArray http://www.freeimagehosting.net/uploads/17858f2e7e.jpg

請幫助..:\

鏈接的功能說明上MSDN

+0

我似乎誤導了你,所以我添加了完整的相關代碼。也增加了截圖。 謝謝大家回覆:) – idcman 2009-11-19 19:57:21

回答

6

你舉一個具體的Windows功能,而這也是真正的realloc(),這是該標準等效。

如果這些函數返回與傳入地址相同的地址,這是因爲原先請求的緩衝區之後的內存未被使用。所以它可以在不移動緩衝區的情況下滿足請求。

但是,如果有兩個快速分配立即連續,例如?也許剛剛請求的內存最終被用於下一次分配。在這種情況下,分配器需要在其他地方找到空間,複製舊緩衝區中的內容,釋放舊緩衝區並返回新緩衝區。

一般來說,要遵循這樣的事情的模式是這樣的:

void *newmem = realloc(oldmem, newsize); 
if (!newmem) 
{ 
    // TODO: handle failure 
    // possibly free(oldmem); depending on how you want to handle errors 
} 
else 
{ 
    oldmem = newmem; 
} 

一個常見的快捷方式,人們採取的是「oldmem = realloc(oldmem, newsize);」,但是這並不像上述的婉約,如發生故障時會泄漏oldmem。根據您的修改

更新:

有一兩件事,我在你的代碼不知道的是這個部分:

if (newSize == 1) 
{ 
    tempArr = (PFEED)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(FEED)); 
} 

這似乎認爲第一分配永遠是大小一。你確定你不是故意說if (feedArray == NULL),然後分配newSize * sizeof(FEED)

二更新:

確定。另一件突出的事情是:

 
    tempArr = (PFEED)HeapReAlloc(heap, HEAP_ZERO_MEMORY, categoryArray, 
           newSize * sizeof(FEED)); 
    // Snip... 

    if (tempArr != NULL) 
    { 
     // Snip... 
     feedArray = tempArr; 

粗體部分應該是相同的。

+0

不,我很確定.. 只在第一次調用時newSize等於1. 重新分配後數組損壞,就像我在屏幕截圖中顯示的一樣... – idcman 2009-11-19 20:10:55

+0

第二次更新:不明白你的意思:\ 我檢查分配的內存不是NULL,如果不是,我開始使用它作爲我的永久性陣列。 再次感謝。 – idcman 2009-11-19 20:29:58

+0

剛剛意識到我是這樣一個愚蠢的屁股! 非常感謝你! 我混淆了兩個相似的功能。 – idcman 2009-11-19 20:32:22

2

從我看到的文檔:

HeapReAlloc的是保證保護存儲器的內容被重新分配,即使新內存在不同的位置分配。保存存儲器內容的過程涉及可能非常耗時的存儲器複製操作。

所以下一個問題是你如何得出數組內容已經改變的結論?你能提供代碼嗎?有可能存在指針問題和/或現有指針現在指向的假設(假設操作系統調用是正確的,並且完全耗盡應用程序代碼可能首先出錯的任何可能性是重要的,因爲雖然錯誤可能與操作系統調用一起存在,因此可能會發現一個功能與此同樣重要的缺陷)。

2

在調用HeapReAlloc之後,原來的categoryArray被釋放,所以你不再擁有它。其他分配可能會將其用於其他目的,並且內容可能已更改。您需要使用tempArr從現在開始:

tempArr = (PFEED)HeapReAlloc(heap, HEAP_ZERO_MEMORY, categoryArray, newSize * sizeof(FEED)); 
cetagoryArray = tempArr; 
+2

你應該在檢查之前檢查錯誤... – asveikau 2009-11-19 19:02:48

0

你在看哪裏打電話給HeapRealloc?你應該看看返回的指針,而不是你打電話後被它釋放的原始指針

相關問題