【问题标题】:How should I fix valgrind's uninitialised value error?我应该如何修复 valgrind 的未初始化值错误?
【发布时间】:2019-04-06 21:00:18
【问题描述】:

我编写了一个小型应用程序,它在某些时候可以处理二进制数据。在单元测试中,我将这些数据与预期的数据进行比较。发生错误时,我希望测试显示十六进制输出,例如:

Failure
      Expected: string_to_hex(expected, 11)
      Which is: "01 43 02 01 00 65 6E 74 FA 3E 17"
To be equal to: string_to_hex(writeBuffer, 11)
      Which is: "01 43 02 01 00 00 00 00 98 37 DB"

为了显示它(并首先比较二进制数据),我使用了the code from Stack Overflow,根据我的需要稍微修改了它:

std::string string_to_hex(const std::string& input, size_t len)
{
    static const char* const lut = "0123456789ABCDEF";

    std::string output;
    output.reserve(2 * len);
    for (size_t i = 0; i < len; ++i)
    {
        const unsigned char c = input[i];
        output.push_back(lut[c >> 4]);
        output.push_back(lut[c & 15]);
    }

    return output;
}

在使用valgrind 检查内存泄漏时,我犯了很多错误,比如这个:

使用大小为 8 的未初始化值
在 0x11E75A: string_to_hex(std::__cxx11::basic_string, std::allocator > const&, unsigned long)

我不确定是否理解它。首先,一切似乎都已初始化,包括我弄错了output。此外,代码中没有提到尺寸 8; len 的值因测试而异,而 valgrind 每次都报告相同的大小 8。

我应该如何解决这个错误?

【问题讨论】:

  • 你确定len 确实是input 的长度吗?为什么现在直接获取字符串长度还是不检查len不大于长度?
  • @VTT:因为我正在处理二进制数据,所以没有什么可以阻止它在内部包含 0x00,因此应用程序无法确定 from 字符串的长度。因此,长度是独立于数据内容确定的,是的,我确信在测试中,len 每次都是正确的值。
  • 存在终止 null 对字符串对象报告的长度没有影响,因此确定长度是微不足道的。无论如何,您可能应该提供 mcve。我怀疑您传递了一个指向字符数组的指针,该指针被隐式转换为std::string,将其裁剪为第一个\0,因此len最终确实大于实际字符串长度。
  • @VTT:检查。这正是发生的事情。将input 类型替换为const char * 可以解决此问题。您想写下答案,以便我投票并接受吗?

标签: c++ memory-management memory-leaks


【解决方案1】:

所以这是将指向char 的指针传递给std::string 类的邪恶隐式构造函数的指针\0 的情况之一。直接的方法是传递一个原始指针,但更好的解决方案是开始使用array_view span 或类似的实用程序类,它们至少在调试版本中为inputlut 提供索引验证。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 2020-07-11
    相关资源
    最近更新 更多