![](/img/trans.png)
[英]C++ difference between automatic type conversion to std::string and char*
[英]Unexpected difference between char* and string with std::getenv
我的代碼看起來像這樣:
#include <cstdlib>
#include <iostream>
#include <string>
std::string string_from_env(std::string var) {
std::string out = std::getenv(var.c_str());
return out;
}
int main() {
const char* x1 = string_from_env("TEST_HOST").c_str();
const char* x2 = string_from_env("TEST_USER").c_str();
const char* x3 = string_from_env("TEST_NAME").c_str();
std::cout << x1 << " " << x2 << " " << x3 << std::endl;
const std::string y1 = string_from_env("TEST_HOST");
const std::string y2 = string_from_env("TEST_USER");
const std::string y3 = string_from_env("TEST_NAME");
std::cout << y1 << " " << y2 << " " << y3 << std::endl;
}
如果我跑
export TEST_HOST=host
export TEST_USER=user
export TEST_NAME=name
g++ --std=c++2a test.cc # version 9.3.0
./a.out
那么 output 是
name name name
host user name
為什么char*
版本導致x1,x2,x3
全部打印name
,而std::string
版本按預期工作?
有沒有辦法可以修改string_from_env
以便相同的代碼打印host user name
而不是name name name
?
std::string::c_str
返回的指針指向string
object 擁有的 memory。 當string
被銷毀(或什至以某種方式發生變異)時,該指針變得無效。
由於在前三個調用中由string_from_env
返回的臨時string
對象不會立即綁定到引用,因此它們在包含 function 調用的完整表達式的末尾被銷毀。 這意味着x1
、 x2
和x3
在創建后立即變為無效。 嘗試從中讀取將導致未定義的行為。
考慮這條線
const char* x1 = string_from_env("TEST_HOST").c_str();
您不存儲調用string_from_env("TEST_HOST")
的結果,因此它返回的臨時字符串將在表達式末尾被銷毀。 所以x1
將指向一個已經被破壞的字符串的內部緩沖區。 您的代碼具有未定義的行為。
x1
, x2
和x3
都指向同一個字符串的原因與小字符串優化有關,這是 std::string 的實現細節
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.