如何通過使用免費名稱編寫包裝函數來解決雙重空閒問題,以便我不需要更改源代碼中的每個免費呼叫?雙免費問題
雙免費問題
回答
不要做
一個簡單的方法是定義你的包裝功能和#定義自由打電話給你的函數。
#undef free
#define free(x) wrapper_free(x)
/* ... */
int *data = malloc(42);
free(data); /* effectively calls wrapper_free(data) */
但是...... 不這樣做!
不要這樣做。
不,真的。修復實際問題。一旦在指針上調用了空閒()之後,代碼應該由而不是由於任何原因持有它。將它清空,所以你不能再釋放它;這將會導致由stale指針解引用導致的任何其他問題也可見。
+1將指針設置爲NULL。這實際上是最簡單的解決方案,永遠不會雙倍免費。無論如何,編寫一個執行'free()'的自定義'my_free()',然後將指針設置爲NULL似乎是確保這一點的最簡單方法。但是,這涉及代碼更改:-) – Joey 2009-09-17 14:31:25
關於包裝器functino的好處,它負責將指針歸零。有些語言甚至包含這些內容,而使用它們總是一個好習慣。 Delphi對象有一個free()方法,但最好使用FreeAndNil()全局函數。當指針已經爲空時,它也不會拋出錯誤。 – 2009-09-17 14:39:52
@Chris:是什麼讓你認爲'free(NULL)'引發錯誤? ANSI標準,第4.10.3.2節:「如果ptr是空指針,則不會發生任何操作。」 – Christoph 2009-09-17 14:50:24
我同意其他職位說,你不應該。主要的是,讓人們看看你的代碼並試圖弄清楚發生了什麼(當他們習慣於只看到釋放內存的空閒時)會更困惑。
如果你正在尋找一行代碼,可以讓你釋放和清除指針,我建議使用一個宏,儘管還有其他方法來做到這一點(創建一個方法,需要一個指針指向你的指針)。
#define FREEANDCLEAR(pointer)\
{\
free(pointer);\
pointer = 0;\
}
編輯 作爲克里斯托弗在評論中提到,你也可以確保用戶使用宏像一個函數(用做結尾用分號線,而像這樣:
#define FREEANDCLEAR(pointer)\
do {\
free(pointer);\
pointer = 0;\
} while(0)
將執行一次,並要求結束分號。
沒有必要檢查'if(pointer)'''free(NULL)'是否有效並且什麼也不做;此外,您可能想在'do..while與包裝這個()'循環來獲取函數的語法 – Christoph 2009-09-17 14:42:13
感謝克里斯託弗,我如果取消了,用在DO增加了第二個實現! – 2009-09-17 15:10:57
去翻答案,計算器問題,"Write your own memory manager"。
在這些答案中使用這些工具或技術將允許您使用內存管理器來檢查這些類型的問題,以便您可以識別並修復這些問題(對於您的問題,許多其他答案表明,使用某些東西並不是一個好主意像這是一個解決方法)。
以下代碼截取對malloc()
,realloc()
和calloc()
進行日誌記錄的調用。
當調用free()
時,它檢查內存是否被預先分配了其中一個函數。否則,程序將被終止。釋放空指針將被報告,但執行將繼續。
頁眉memdebug.h
:
#undef free
#define free(PTR) memdebug_free(PTR, #PTR, __FILE__, __func__, __LINE__)
#undef malloc
#define malloc(SIZE) memdebug_log(malloc(SIZE))
#undef realloc
#define realloc(PTR, SIZE) memdebug_log(realloc(PTR, SIZE))
#undef calloc
#define calloc(COUNT, SIZE) memdebug_log(calloc(COUNT, SIZE))
#ifndef MEMDEBUG_H
#define MEMDEBUG_H
extern void memdebug_free(void *ptr, const char *ptr_arg, const char *file,
const char *func, int line);
extern void *memdebug_log(void *ptr);
#endif
來源memdebug.c
:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef MEMDEBUG_TABLE_SIZE
// log 16k allocations by default
#define MEMDEBUG_TABLE_SIZE 0x4000
#endif
static void *alloc_table[MEMDEBUG_TABLE_SIZE];
static size_t top;
void *memdebug_log(void *ptr)
{
assert(top < sizeof alloc_table/sizeof *alloc_table);
alloc_table[top++] = ptr;
return ptr;
}
void memdebug_free(void *ptr, const char *ptr_arg, const char *file,
const char *func, int line)
{
if(!ptr)
{
fprintf(stderr,
"%s() in %s, line %i: freeing null pointer `%s` -->continue\n",
func, file, line, ptr_arg);
return;
}
for(size_t i = top; i--;)
{
if(ptr == alloc_table[i])
{
free(ptr);
--top;
if(i != top) alloc_table[i] = alloc_table[top];
return;
}
}
fprintf(stderr,
"%s() in %s, line %i: freeing invalid pointer `%s`-->exit\n",
func, file, line, ptr_arg);
exit(EXIT_FAILURE);
}
+1,這應該適用於嵌入式環境或valgrind不可用時的其他情況。 – 2009-09-17 23:22:25
除了所有其他的答案和參考內存管理的研究與開發等。
當雙自由存在這樣的指示,事情並沒有按照正確的順序完成的代碼等錯誤發生
當我大約10年前開始使用Java,大家都稱讚Java的,因爲你沒有不得不煩擾新/刪除。
我很困擾(因爲我是用C/C++開發的),因爲除了malloc/free之外,突然間所有的open/close,create/destroy,鎖定/解鎖模式都以多種方式出現可能會被打破,因爲大家都認爲所有清理都是自動的。
所以當你有這些問題,你可能有其他的問題遲早的事。資源不足,數據庫連接被佔用,文件鎖定在文件系統上。
雙人自由是你的程序不具有良好的結構的信號,被分配在一個層e.g的事情,而在另一個釋放。
- 1. C雙免費問題
- 2. Java免費圖表問題
- 3. 雙免費電話號碼
- 4. 雙免費或功能
- 5. 免費的雙向鏈表
- 6. 雙免費()或損壞:C++
- 7. C++不同免費訂單的雙重免費錯誤
- 8. 程序結束時沒有免費的雙免費或腐敗
- 9. Scrolling GridView導致GC_FOR_ALLOC免費問題
- 10. Magento - Google Checkout免費送貨問題
- 11. Ç調試問題,免費方法
- 12. Lambda微積分免費可變問題
- 13. 雙免費或腐敗崩潰
- 14. 錯誤的對象0xb50dd20:雙免費
- 15. 雙免費或腐敗的錯誤C++
- 16. Gtest和Gmock - 雙重免費或腐敗
- 17. 搖晃指針和雙免費
- 18. 免費商店的雙鏈表
- 19. 雙免費或腐敗(fasttop)錯誤
- 20. 這是C中的雙倍免費嗎?
- 21. Abaqus免費免費分析?
- 22. 免費的免費動態內存()
- 23. 雙:: TryParse問題
- 24. 雙總問題
- 25. 雙擊問題
- 26. 雙iframe問題
- 27. 條收費問題
- 28. Akamai收費問題
- 29. 問題容器:*** glibc的檢測***免費():無效指針:0x41e0ce94 ***
- 30. NGINX餅乾免費域名的配置設置小問題
相關:http://stackoverflow.com/questions/678254/c-function-conflict – dmckee 2009-09-17 15:04:44
也相關:http://stackoverflow.com/questions/617554/override-a-function-call-in-c – dreamlax 2009-09-18 09:25:25
對不起,在那裏吹着我自己的號角 – dreamlax 2009-09-18 09:26:04