2010-03-03 89 views
2

在我的模板功能,我有以下代碼:堆腐敗問題

TypeName myFunction() 
{ 

    TypeName result; 
    void * storage = malloc(sizeof(TypeName)); 

    /*Magic code that stores a value in the space pointed to by storage*/ 

    result = *(TypeName *)storage; 

    free(storage); 
    return result; 
} 

這會導致error.If我不調用free()函數的「檢測出堆損壞」,誤差不發生,但我擔心我正在創建一個內存泄漏。如何返回「存儲」的值然後取消分配內存?

+1

線索在「假設」一詞中。什麼是'sizeof Typename'? – 2010-03-03 17:30:03

+3

你的錯誤可能在「魔法代碼」中。我們可以偷看嗎? – 2010-03-03 17:31:27

回答

1

什麼:

TypeName myFunction() { 
    TypeName result; 
    void* storage = &result; 

    /*Magic code that stores a value in the space pointed to by storage*/ 

    return result; 
} 

在這裏,所有的變量將被存儲在堆棧上,所以你不應該遇到堆相關的問題(這依賴於你的「神奇」的代碼做什麼)。

有沒有理由將您的storage陣列與result分開?如果結果將被簡單地複製到result中,那麼更有意義(恕我直言)只使用一個對象(並且根據需要保留指向它的void*指針或根據需要保留指定&result)。

如果有一個理由使用一個單獨的storageresult,你會使用TypeName storage = new TypeNamedelete,而不是malloc(4)free可能獲得更好的milage。

+0

我試試看,坦率地說我把結果和存儲分開的習慣: 每次我寫一個新函數,我放入的第一行是 型的結果; 返回結果; 所以IDE停止抱怨:) 編輯:完美的作品:)感謝一堆,我想這顯示了我有與參考:)是多麼真實的生活經驗:)) – 2010-03-03 18:41:06

+0

是的,讓我們用堆棧腐敗替換堆腐敗爲後者很難注意到...... – sbk 2010-03-03 18:45:20

+0

請詳細說明,你認爲這個動作會引入什麼問題?我真的沒有看到可能對堆棧造成的危害,所以如果你有一些想法,它會幫助你我很多:)) – 2010-03-03 19:04:45

2

不要這樣稱呼它:

TypeName result; 
void * storage = malloc(4); 

你應該把它

TypeName result; 
void * storage = malloc(sizeof(TypeName)); 

反正代碼看起來很奇怪:)

+0

這不是實際的代碼,它是造成我的問題的一個小縮放模型:)你是完全正確的,不應該有魔法「4」在任何數據庫周圍徘徊:)) – 2010-03-03 18:32:44

3

你並不需要分配存儲 ,你可以將你的結果變量轉換成一個可以實現你魔法的函數。像這樣的東西。

void magic(void *buffer) 
{ 
    // magic stuff 
} 

TypeName foo() 
{ 
    TypeName result; 
    magic(&result); 
    return result; 
} 

或者當然你可以有你的類型名結構設置爲位字段或任何你的魔碼操作...

+0

+1閱讀問題,挖掘過去的機制,並提出最簡單的解決方案。 – 2010-03-03 17:53:43

+0

是的,通常這將是明智的做法...但是正如它經常發生的那樣,我無法在我的情況下這樣做:S一些魔法代碼涉及彙編和堆棧操作,所以我實際上無法再調用其他函數有:S:S – 2010-03-03 18:35:13

0

你爲什麼malloc 4個字節,但澆鑄的類型名稱TypeName?這絕對看起來很奇怪!

其他答案暗示你是什麼......!

希望這會有所幫助, 最好的問候, 湯姆。

1

我覺得你的困惑就在於這一行:

void * storage = malloc(4); 

看起來你是要爲4個字節的指針分配空間,但是這不是你需要做什麼。讓我們打破行分爲兩個步驟:

void * storage;   // This allocates 4 bytes for a variable of type "pointer to void" 
storage = malloc(4); // This allocates 4 _more_ bytes and sets "storage" to their address. 

我假設從Typename型到使用這種效果分配給storage內存變量「神奇」的代碼拷貝數據:

memcpy(storage, data_from_a_Typename_variable, sizeof(Typename)); 

因此,如果sizeof(Typename)大於分配給storage的4個字節,您將看到堆損壞錯誤。

至於其他的答案表明,你需要做的是爲Typename可變分配足夠的空間,這樣的:

void * storage = malloc(sizeof(Typename)); 

但是,正如Liz Albin建議,你已經在一個Typename分配空間result因此將&result(void *) &result傳遞給魔術功能會更簡單。