【问题标题】:Why does returning a C-string from a function result in random characters?为什么从函数返回 C 字符串会导致随机字符?
【发布时间】:2017-09-20 05:45:15
【问题描述】:

我不得不停止编写这么多项目,因为我受够了这个奇怪的怪癖,我已经受够了去问和冒着看起来像个白痴的风险,所以这里......

我写了一个这样的函数:

const char* readFileToString(const char* filename) {
    const char* result;
    std::ifstream t(filename);
    std::stringstream buffer;
    buffer << t.rdbuf();
    result = buffer.str().c_str();
    return result;
}

我希望,如果file.txt 包含hello,那么readFileToString("file.txt") 应该返回hello。相反,它返回乱码文本,类似于H�rv�0。但是,如果我在返回之前添加std::cout &lt;&lt; result;,它将打印hello

这是 C++ 的一些奇怪的、不可能的怪癖吗?我该如何解决?

【问题讨论】:

  • 返回指向本地或临时变量的指针很少是一个好主意。只需使用 std::string,按值返回。

标签: c++ string scope


【解决方案1】:

这既不奇怪也不不可能;您返回了一个指向超出范围的缓冲区的指针。 const char* 不“拥有”字符串数据,它只是引用它。或者,它曾经!一旦返回,该指针现在无效。你不应该取消引用它。

我建议你坚持使用std::string,而不是冒险使用高级指针技术。

std::string readFileToString(const char* filename)
{
    std::ifstream t(filename);
    std::stringstream buffer;
    buffer << t.rdbuf();
    return buffer.str();
}

很遗憾,我不知道有什么方法可以避免在此处复制。

如果您不介意稍微改组您的设计,并且如果您有办法避免流到字符串的复制,您可以这样做:

void readFileToStream(const char* filename, std::ostream& os)
{
    std::ifstream t(filename);
    os << t.rdbuf();
}

您可能希望返回 bool 来表示流的状态,但无论如何您都可以在调用点执行此操作。

【讨论】:

    【解决方案2】:

    请看下面的评论:

    const char* readFileToString(const char* filename) {
        const char* result;
        std::ifstream t(filename);
        std::stringstream buffer; // Behind the scenes some memory will/is allocated
        buffer << t.rdbuf();      // Memory is getting filled 
        result = buffer.str().c_str(); // Getting the address of that memory
        return result;
        // Buffer getting destroyed along with the allocated memory (what result points to)
    }
    

    .. 这里的结果指向一个无效的内存位置

    因此它被损坏了

    【讨论】:

      猜你喜欢
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 2020-07-06
      • 2021-05-12
      • 1970-01-01
      • 2014-11-06
      相关资源
      最近更新 更多