string s = "Hello world";
char* s2 = s.c_str();
將S2在棧上分配,或在人堆裏?換句話說......我需要刪除s2嗎?
s2
在堆棧上,是的。但是,它是一個指向字符的指針(在這種情況下,恰好是在s
的文本內容的ASCIIZ表示中的第一個字符)。該文本本身就是s
對象覺得構建該表示的地方。不過,他們喜歡實現,但std::string
的關鍵實現選擇是他們是否提供了「短字符串優化」,允許將非常短的字符串直接嵌入到s
對象中,以及「Hello world」是否足夠短從該優化受益:
- 如果是這樣,那麼
s2
將指向堆內s
- 否則分配的內存,內部
s
會有一個指向空閒存儲/堆分配的內存,其中的「Hello world \ 0「內容將會出現,其地址將由.c_str()
返回,並且s2將是該值的副本。
注意c_str()
是const
,所以你的代碼編譯,你需要改變const char* s2 = ...
。
您不需要刪除s2,no。 s2分數據仍由s
對象擁有和管理的數據將由於s
的非const
方法或s
超出範圍的任何調用而失效。
string s = new string("Hello, mr. heap...");
char* s2 = s.c_str();
現在的s2上堆,其起源是在堆上?
此代碼不能編譯,因爲s
不是一個指針和一個字符串沒有像string(std::string*)
構造。你可以將其更改爲:
string* s = new string("Hello, mr. heap...");
......或者......
string s = *new string("Hello, mr. heap...");
後者創建了一個內存泄漏和沒有用處,所以我們假設前者。然後:
char* s2 = s.c_str();
...需要成爲...
char* s2 = s->c_str();
現在的s2上堆,其起源是在堆上?
是的。在所有的情況下,特別是如果s
本身在堆上,然後:
- 即使裏面有
s
短串優化緩衝到c_str()
產生一個指針,它必須是在堆中,否則
- 如果
s
使用指向更多內存的指針來存儲文本,則該內存也將從堆中分配。
但同樣,即使知道了肯定s2
指向堆分配的內存,你的代碼並不需要解除分配內存 - 它會自動完成時s
被刪除:
string* s = new string("Hello, mr. heap...");
const char* s2 = s->c_str();
...use s2 for something...
delete s; // "destruct" s and deallocate the heap used for it...
中當然,通常使用string s("xyz");
更好,除非您需要超出本地範圍的使用期限,否則使用std::unique_ptr<std::string>
或std::shared_ptr<std::string>
。
有趣,所以,你永遠不會釋放char *,因爲這樣做會釋放字符串中的內部數據? c_str()字面上保持與字符串使用的實際數據相同的地址?多次調用.c_str()會以這種方式返回相同的地址? (只是澄清,所以我知道我明白) – 2012-01-12 23:03:51
@Georges這些問題的答案取決於你是否使用最新的標準或舊標準。你可能想澄清哪一個你感興趣。 – 2012-01-12 23:05:45
@ R.MartinhoFernandes更好地使用最新的標準。這將是有趣的,但要知道這個標準是多麼新近 – 2012-01-12 23:06:32