簡體   English   中英

為什么在返回字符串的函數上調用 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_copySomeFunction()的返回值的副本。 現在在它上面調用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 的平台,它已經存在了。

  1. SomeFunction() 方法中的“ string str ”是SomeFunction()中的局部變量,只存在於SomeFunction() SomeFunction()范圍內;

  2. 由於SomeFunction()方法的返回類型是字符串,而不是字符串的引用,因此在 " return str; " 之后, SomeFunction()將返回str的值的副本,該副本將作為臨時值存儲在某個地方內存方面,調用SomeFunction()后,臨時值會立即銷毀;

  3. string str = SomeFunction(); ”將SomeFunction() () 返回的臨時值存儲到字符串str中,實際上是該值的副本並存儲到str中,分配了一個新的內存塊,並且str的生存期大於SomeFunction()返回的臨時值,在 " ; " SomeFunction()調用完成后,返回的臨時值立即銷毀,內存被系統回收,但該值的副本仍保存在str . 這就是為什么“ const char* strConverted = str.c_str(); ”可以得到正確的值,實際上c_str()返回的是str的初始元素的指針( str指向的字符串值的第一個元素內存地址),而不是返回SomeFunction()的臨時值;

  4. const char* charArray= SomeFunction().c_str(); ”不一樣,“ SomeFunction().c_str() ”會返回一個指向返回臨時值的初始元素的指針(返回臨時字符串的首元素內存地址) value),但是在調用SomeFunction()之后,返回的臨時值被銷毀,並且該內存地址被系統重用, charArray可以獲取該內存地址的值,但不是您期望的值;

使用 strcpy 將字符串復制到本地定義的數組中,您的代碼將正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM