2010-08-30 99 views
2

我有一個C++類爲字符串,像一員:C++字符串重新分配,舊字符串是否正確釋放?

class Phone { 
string name; 

void foo() 
    { 
    name = string("new_name"); 
    } 
} 

現在,「foo」函數中,我重新分配字符串「NEW_NAME」。我的問題是:

  • 舊的空串會發生什麼?它是否正確「釋放」?它仍然佔用內存嗎?
  • 現在我初始化Phone的構造函數中的字符串string(「old_name」)。這與之前的空字符串是否一樣?舊字符串「old_name」在這裏會發生什麼?

回答

6

是的,std::string爲您管理內存。 (這是它存在的原因之一!)它是如何實現的,這是一個實現細節(例如,它可能使用寫時複製,引用計數或深度複製語義),但在大多數情況下,std::string將始終正確釋放內存,如果它不再需要的話。

當然,這是假定在賦值運算符或std::string的析構函數的實現中沒有錯誤(對於實現非默認賦值運算符/析構函數的所有類都是如此)。

+0

非常感謝......這意味着,當我正確理解它時,您真的只需要關心用「新」創建的內容以避免內存泄漏? (除了mallocs,當然..) – 2010-08-30 15:04:44

+0

@JanRüegg:Sort。但是你總是可以圍繞這些問題進行設計。閱讀RAII。請參閱http://www2.research.att.com/~bs/bs_faq2.html#finally – dirkgently 2010-08-30 15:07:30

+0

@Jan - 正確設計的類(例如,可能使用RAII)將極大地幫助您編寫不會泄漏內存的代碼。請參閱http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization – 2010-08-30 15:20:17

1
  • 假設賦值運算符正確寫入,析構函數將被調用。
  • 假設析構函數被正確寫入,所使用的內存被釋放。
+1

或者,賦值運算符不會調用析構函數,並將舊分配的內存重新用於新值。無論如何,這是分配運營商的責任。 – 2010-08-30 14:58:34

+0

在大多數情況下,賦值操作符不會調用析構函數。在某些情況下,'operator ='是通過拷貝構造和交換'* this'與本地來實現的,之後本地將被銷燬。只有在極少數情況下,我已經看到'operator ='以析構函數和就地構造的形式實現......但是在很多情況下,賦值操作符都是在不調用析構函數的情況下編寫的。 – 2010-08-30 15:18:58

2

如果是std::string我們正在討論,那麼一切都被正確釋放。

但是,實際情況下究竟發生了什麼。幾個std :: string實現使用某種形式的引用計數,所以它依賴於實現。

另外請注意,您的代碼做同樣的:

name = "new_name"; 

...甚至更明確:

name.assign("new_name"); 
1

發生到老,空字符串是什麼?它是否正確「釋放」?它仍然佔用內存嗎?

它通常不應該佔用太多的內存(只要你還沒有初始化它)。在分配時,字符串可能會重新分配給。你在做什麼是這樣的:

  • 創建其被釋放一次分配是在上使用這個臨時的;
  • 複製構造一個新的字符串,然後將其設置爲原來的name變量臨時string對象。

任何內存重新分配都將正確釋放原始內存。注意:根據您的設置,編譯器可能會或可能不會優化某些步驟。

現在我在 構造電話的初始化字符串來 字符串(「舊名稱」)。這是否與前面的空字符串一樣? ? 這裏發生的舊字符串 「old_name」?

取決於。如果你正在使用初始化列表,那麼不,它是不一樣的。沒有任務;只有拷貝構造函數被調用。

相關問題