2015-10-08 171 views
-2

目前我一直對學校作業感興趣,正在處理一些非常討厭的內存泄漏問題。在調試時,我將問題的一部分縮減爲一段代碼。爲什麼此代碼會產生內存泄漏?

這裏是代碼,我調整來說明泄漏的極度簡化版本:

_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); 
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); 
    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); 
    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); 
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); 
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); 

    do { 
     char *name = new char; 
     char *cname = new char[10]; 
     cin >> cname; 

     name = cname; 
     delete [] name; 

    } while(false); 

    _CrtDumpMemoryLeaks(); 

所以我的問題是,爲什麼這產生了內存泄漏?我試過一堆東西來解決它,但沒有任何工作。

編輯:

嗯,看來我已經被誤解的指針是如何運作的。出於某種原因,我假設指針初始化時沒有指向NULL而不是內存塊,因此不需要處理。

簡單的問題可以得到簡單的答案。謝謝。

+0

'的char * name = nullptr'將指向沒有記憶,但調用'new'分配內存(並因此需要被釋放) – Tas

+0

您分配一個字符,分配10個字符,做一些東西,刪除10個字符,但不要刪除單個字符(你實際上並不需要分配,但你做了)。 – immibis

回答

2

您呼叫新的兩次,但只刪除一次。

+0

但更糟糕的是,他覆蓋了他的一個分配,之後永遠不能刪除,而第一個分配甚至不需要。 – Les

0

顯然你還沒有嘗試刪除name - 第一char您重置name到別的東西,失去所有引用到初始塊之前分配...

+0

Downvoter請解釋一下嗎? – John3136

+0

+0.9抵消downvote原因這篇文章沒有錯 – Tas

+1

@Tas,是一個陰暗的嘗試繞過「+一個」的評論禁止?如果是這樣,它可能應該是'+0.999 ...'。或者「+ one」作爲另一種選擇,顯然:-) – paxdiablo

1

你做char* name = new char;

,但後來你用name = cname;

代替(忘記)name的值,以便原始new char從不被刪除。

0

只需按照代碼,看看有什麼被分配和釋放:

char *name = new char;  // Block 1, name references it 
char *cname = new char[10]; // Block 2, cname references it 
: 
name = cname;    // name/cname now reference block 2 *** 
delete [] name;    // free up block 2 

您可以在***行,你失去指針塊1看到,因此,有你的內存泄漏。即使你有代碼試圖釋放塊1,你不再在那之後有一個引用它。

如果你要失去所有訪問內存塊,你最好先自由起來:

char *name = new char;  // Block 1, name references it 
char *cname = new char[10]; // Block 2, cname references it 
: 
delete name;     // free up block 1 
name = cname;    // name/cname now reference block 2 *** 
delete [] name;    // free up block 2 

至於您的評論:

對於一些原因是我假設指針初始化時沒有指向NULL而不是內存塊,因此不需要處理。

如果您沒有指定,指針將被初始化爲什麼,這取決於幾個因素。然而,這裏並不重要,因爲你初始化它。如果你想有一個指針設置爲NULL,只要做到這一點:

char *name = 0; // not "new char". 
相關問題