2010-07-30 145 views
2

這是一個關於C++代碼的內存管理問題。內存管理

using namespace std; 
#include <iostream> 
#include <string.h> 

int main() 
{ 
string a="first"; 
string *b= new string; 
*b=a; 
a="second"; 
cout << *b << ", " << a; 
delete b; 
return 0; 
} 

我們可以取消分配存儲b指向的字符串的內存塊。 我假設這意味着b完成後不再有任何意義。 我們可以釋放b來釋放一些內存。爲什麼我們不能釋放一個? 我知道我們只能刪除/釋放指針,但字符串a必須佔用一些內存。 有什麼方法可以釋放字符串a佔用的內存? 如果有足夠的字符串以與a初始化相同的方式初始化,那麼內存用完了嗎?

回答

0

分配給a的內存將在函數返回後自動釋放。

4

字符串a在堆棧中聲明。您不能手動釋放它,但一旦它離開作用域時它將自動釋放(例如,當封閉函數返回時)。如果您需要釋放內存中間函數,請動態聲明它(如同您爲b所做的那樣)。

+0

+1你的答案比我的更完整。 – karlphillip 2010-07-30 16:33:05

+0

或者您可以將字符串放在較小的範圍內......並不是在大多數情況下都是值得的。 – 2010-07-30 17:08:06

2

自動對象(如您的a)在外出時會被銷燬。見下面的例子:

int main() 
    { 

    { 
    string a="first"; 
    string *b= new string; 
    *b=a; 
    a="second"; 
    cout << *b << ", " << a; 
    delete b; //b gets freed 
    } //a gets freed because it has gone out of scope 
/* You can write more code here that does not need a */ 
return 0; 

}

0

a這裏是自動分配的「堆棧」,並會自動銷燬/釋放時,它超出範圍。

當您使用動態內存與new/malloc時,它被分配到「堆」,這只是程序可用的一堆內存。你必須手動管理這個,程序不知道什麼時候擺脫它。

如果你真的在這種情況下擔心內存,你應該只使用動態內存分配。

編輯:這給了比我想說的更完整的解釋: http://en.wikipedia.org/wiki/Malloc#Rationale

3

字符串由包含指向存儲的字符串數據的小物件,它的壽命是由管理的目的。通常不需要擔心對象自身佔用的內存,但是如果字符串很大,則可能需要釋放存儲空間而不破壞對象。

調用clear()或從emptry字符串進行賦值可能不會釋放存儲空間。確保它被釋放的方法是將字符串與新構建的臨時對象交換;臨時的析構函數將釋放它。

string().swap(a); // replaces `a` with an empty string 

您也可以對任何標準容器執行此操作。

3

這很尷尬。

<string.h>是C標頭。它沒有定義string。它看起來像你的版本<iostream>直接或間接包括<string>,否則會出現錯誤。

字符串(由成對引號分隔的那些東西)可能在任何地方,包括只讀內存段。 (他們確實佔用了內存,但是你必須有很多文本才能產生重大影響:類似戰爭與和平不會佔用完整的大小。)在這種情況下,std::string是用該值進行初始化,然後再賦值給它。 std::string處理它使用的內存。

在C++中,幾乎沒有理由指向std::stringstd::string沒有內容就佔用太多空間,並且管理內容本身的內存。你是否與char *混淆?

new一個爲bstd::string,然後再指定地址b沒有delete荷蘭國際集團的內存。這是內存泄漏。你爲bnew仍然分配在那裏,但它沒有辦法delete它,所以它會佔用內存的程序期間。

然後,一旦您將a的地址分配給b,您delete b;。這是一個糟糕的想法,並可能以一種可能無法預測的方式搞砸重要事情。只有您用new獲得的delete內存。 (這裏delete ing的重要不是b是一個指針,應該刪除,但它指向的內存不是通過new得到的。)

內存管理的工作原理與此類似。字符串文字被分配到某處。所有你知道的是,你不應該試圖改變它或以任何方式它delete它。使用該值,不要碰其餘的。 A std::string爲其內容管理內存,並在其析構函數中處理該內存。一個在函數或其他塊中聲明的變量一旦超出範圍就會被銷燬(儘管它可能指向的內容不會被自動銷燬;只有當它是一個智能指針或管理自己的內存或其他內容時)。如果你的內存是new,請不要丟棄指針值,直到它爲delete d。如果您還沒有new ed內存,請不要delete它。

+0

+1代碼的詳細說明。 – rturrado 2010-08-01 18:03:37

+0

嗯,實際上這裏沒有內存泄漏:作者寫過 'string * b = new string; * b = a; ' 如果他寫道: ' string * b = new string; b =&a; ' 雖然同意你的其他言論。 – Haspemulator 2010-08-05 03:35:11

+0

+1提到字符串文字內存位置。它們通常駐留在應用程序的靜態內存中,而不是堆棧或堆中。這就是爲什麼你不應該刪除一個字符串文字的指針。 – Zoomulator 2012-01-17 20:06:42