【问题标题】:Variable always empty变量始终为空
【发布时间】:2020-06-19 06:51:29
【问题描述】:

我在初始化全局变量时遇到问题。我的 C++ 有点生锈,所以我不记得我的代码无法正常工作的原因。

文件.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 是全球性的无关。我将定义放在 main 中,当我尝试打印 write_path 时,它仍然是空的

【问题讨论】:

    标签: c++ initialization global lifetime temporary


    【解决方案1】:

    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 始终是一个有效的指针。

    【讨论】:

      【解决方案2】:
      const char * write_path = &(std::string(getenv("FIFO_PATH")) + "/pythonread_fifo")[0];
      

      构造一个临时的std::string,获取它的第一个字符的地址,然后丢弃字符串,从而删除底层的char数组。这是 UB。

      最好只使用std::string 并在需要const char* 时使用c_str()

      【讨论】:

      • 天哪,我知道我的 C++ 生锈了,只是没有生锈……我完全忘记了临时字符串会被释放……
      【解决方案3】:

      您正在创建一个 临时 std::string 对象,并获得指向其第一个字符的指针。一旦表达式&amp;(std::string(getenv("FIFO_PATH")) + "/pythonread_fifo")[0]结束,临时对象被破坏,这个指针就会失效。

      也为write_path 使用std::string 对象,在main 函数中定义它,并在需要以null 结尾的字符串时使用字符串的c_str 函数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-05
        • 1970-01-01
        • 2021-12-22
        • 1970-01-01
        • 1970-01-01
        • 2021-07-07
        相关资源
        最近更新 更多