我在初始化全局变量时遇到麻烦。我的C ++有点生锈,所以我不记得我的代码无法正常工作的原因。
file.cpp
const char * write_path = &(std::string(getenv("FIFO_PATH")) + "/pythonread_fifo")[0];
int main(int argc, char**argv)
{
std::cout << "printing a string: ";
std::cout << (std::string(getenv("FIFO_PATH")) + "/pythonread_fifo\n");
std::cout << "printing a const char*: ";
std::cout << &(std::string(getenv("FIFO_PATH")) + "/pythonread_fifo")[0] << std::endl;
std::cout << "printing write_path:";
std::cout << write_path;
std::cout << write_path << std::endl;
std::cout << "printing FIFO_PATH:" << std::string(getenv("FIFO_PATH"));
}
作为前提:FIFO_PATH已正确添加到bashrc中,并且可以工作,但是,当我启动该程序时,这是输出:
printing a string: /home/Processes/FIFOs/pythonread_fifo
printing a const char*: /home/Processes/FIFOs/pythonread_fifo
printing write_path:
printing FIFO_PATH:/home/Processes/FIFOs
您可以看到write_path
完全为空。
对我来说,甚至更奇怪的是,如果我将write_path定义为:
const char * write_path = "/home/Processes/FIFOs/pythonread_fifo";
然后write_path
不再为空,它已正确初始化并打印。
我该如何解决?或至少是为什么会发生这种情况?
编辑:该问题与write_path
全局无关。我将定义放在主要内容中,当我尝试打印write_path
时,它仍然是空的
答案 0 :(得分:6)
write_path
初始化为指向temporary std::string
的第一个元素的指针,在将完整表达式(write_path
)悬空,取消引用之后,它将立即被销毁它会导致UB。
您可以直接使用std::string
,也可以使用命名的std::string
,然后从中获取指针。
std::string s = std::string(getenv("FIFO_PATH")) + "/pythonread_fifo";
const char * write_path = &s[0]; // or s.c_str()
另一方面,
const char * write_path = "/home/mverrocc/dss_cp/dss-cp/Processes/FIFOs/pythonread_fifo";
工作正常,c-style string literal具有static storage duration,并且在程序生命周期内存在内存中,因此write_path
始终是有效的指针。
答案 1 :(得分:3)
const char * write_path = &(std::string(getenv("FIFO_PATH")) + "/pythonread_fifo")[0];
构造一个临时std::string
,获取其第一个字符的地址,然后丢弃该字符串,从而删除底层的char数组。这是UB。
最好只使用std::string
,并在需要c_str()
时使用const char*
答案 2 :(得分:2)
您正在创建一个临时 std::string
对象,并获得一个指向其第一个字符的指针。临时对象被破坏后,一旦表达式&(std::string(getenv("FIFO_PATH")) + "/pythonread_fifo")[0]
结束,此指针将失效。
也将std::string
对象用于write_path
,在main
函数中定义它,并在需要以null终止的情况下使用字符串的c_str
函数字符串。