[英]Why does this work: returning C string literal from std::string function and calling c_str()
[英]Why does calling c_str() on a function that returns a string not work?
我有一個返回字符串的函數。 但是,當我調用它並對其執行c_str()
以將其轉換為const char*
時,它僅在我先將其存儲到另一個字符串中時才有效。 如果我直接從函數中調用c_str()
,它會將垃圾值存儲在const char*
中。
為什么會這樣? 感覺好像我在這里遺漏了一些非常基本的東西......
string str = SomeFunction();
const char* strConverted = str.c_str(); // strConverted stores the value of the string properly
const char* charArray= SomeFunction().c_str(); // charArray stores garbage value
static string SomeFunction()
{
string str;
// does some string stuff
return str;
}
SomeFunction().c_str()
為您提供一個指向臨時變量的指針( SomeFunction
主體中的自動變量str
)。 與引用不同,在這種情況下,臨時對象的生命周期不會延長,最終您會看到charArray
是一個懸空指針,解釋您稍后在嘗試使用charArray
時看到的垃圾值。
另一方面,當你這樣做
string str_copy = SomeFunction();
str_copy
是SomeFunction()
的返回值的副本。 現在在它上面調用c_str()
會給你一個指向有效數據的指針。
函數返回的值對象是臨時的。 c_str()
的結果僅在臨時的生命周期內有效。 在大多數情況下,臨時的生命周期是到完整表達式的末尾,通常是分號。
const char *p = SomeFunction();
printf("%s\n", p); // p points to invalid memory here.
解決方法是確保在完整表達式結束之前使用c_str()
的結果。
#include <cstring>
char *strdup(const char *src_str) noexcept {
char *new_str = new char[std::strlen(src_str) + 1];
std::strcpy(new_str, src_str);
return new_str;
}
const char *p = strdup(SomeFunction.c_str());
注意strdup
是一個 POSIX 函數,所以如果你是一個支持 POSIX 的平台,它已經存在了。
SomeFunction() 方法中的“ string str
”是SomeFunction()
中的局部變量,只存在於SomeFunction()
SomeFunction()
范圍內;
由於SomeFunction()
方法的返回類型是字符串,而不是字符串的引用,因此在 " return str;
" 之后, SomeFunction()
將返回str
的值的副本,該副本將作為臨時值存儲在某個地方內存方面,調用SomeFunction()
后,臨時值會立即銷毀;
“ string str = SomeFunction();
”將SomeFunction()
() 返回的臨時值存儲到字符串str
中,實際上是該值的副本並存儲到str
中,分配了一個新的內存塊,並且str
的生存期大於SomeFunction()
返回的臨時值,在 " ;
" SomeFunction()
調用完成后,返回的臨時值立即銷毀,內存被系統回收,但該值的副本仍保存在str
. 這就是為什么“ const char* strConverted = str.c_str();
”可以得到正確的值,實際上c_str()
返回的是str
的初始元素的指針( str
指向的字符串值的第一個元素內存地址),而不是返回SomeFunction()
的臨時值;
“ const char* charArray= SomeFunction().c_str();
”不一樣,“ SomeFunction().c_str()
”會返回一個指向返回臨時值的初始元素的指針(返回臨時字符串的首元素內存地址) value),但是在調用SomeFunction()
之后,返回的臨時值被銷毀,並且該內存地址被系統重用, charArray
可以獲取該內存地址的值,但不是您期望的值;
使用 strcpy 將字符串復制到本地定義的數組中,您的代碼將正常工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.