变量始终为空

时间:2020-06-19 06:51:29

标签: c++ initialization global lifetime temporary

我在初始化全局变量时遇到麻烦。我的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时,它仍然是空的

3 个答案:

答案 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函数字符串。