为什么 Valgrind 会给出 "Invalid read of size 1" 错误?

Why does Valgrind give "Invalid read of size 1" error?

Valgrind 给我一个无效的读取错误:

==37561== Invalid read of size 1
==37561==    at 0x7E81: strlen (vg_replace_strmem.c:427)

对于 class 中的以下代码(我认为这可能与尾随 [=13=] 有关,但我不确定)。

std::queue<std::string> errorLog;  ///< FIFO used to store errors

const char *Monitor::popErrorFromErrorLog() {
    if (!errorLog.empty()) {
        std::string str = errorLog.front();
        errorLog.pop();
        return str.c_str();
    } else {
        return nullptr;
    }
}

void Monitor::reportError(std::string s) {
    std::ostringstream err;
    err << "Error reported: " << s << std::endl;
    errorLog.push(err.str());
}

请问这里出了什么问题?

您正在 return 指向不再存在的 std::stringc_str 指针:您将其从堆栈中弹出并将其内容复制到局部变量,然后您return 该局部变量的 c_str 指针,它作为函数 returns.

被销毁

至于解决方案,为什么不 return std::string 而不是求助于 C 字符串?

std::string str = errorLog.front(); 创建本地 std::string。当您使用 return str.c_str(); 时,您正在 return 指向 std::string 包装的 c 字符串的指针。一旦 return 发生,字符串就会被销毁,现在您已经 return 编辑了一个指向超出范围的内存的指针。

我只想 return 一个 std::string 所以你不必担心。如果你做不到,那么你将不得不动态分配存储空间(新{}),然后你必须记得在完成后清理它(delete[])。