[英]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.