瓦尔格林德:在字符[]到标准::向量迁移之后"Invalid write of size 1"<char>



我在c ++中有一个非常简单的hexlify方法,它基于python的binascii实现。

std::string Hexlify(const std::string& iData)
{
    // the same as python binascii.b2a_hex
    const size_t len = iData.size() << 1; // output will be twice as long
    char hex[len];
    const char* curdata = iData.data();
    char* curhex = hex;
    const char* end = curdata + iData.size();
    char c;
    // from python's implementation (2.7.1, if it matters)
    while(curdata <= end)
    {
        c = (*curdata>>4) & 0xf;
        c = (c>9) ? c+'a'-10 : c + '0';
        *(curhex++) = c;
        c = (*curdata) & 0xf;
        c = (c>9) ? c+'a'-10 : c + '0';
        *(curhex++) = c;
        curdata++;
    }
    return std::string(hex, len);
}

这工作得很好。

现在,hex char[] 在堆栈上分配,在处理巨大的缓冲区时这可能是一个问题,这就是为什么我想将其迁移到std::vector以从堆分配中受益的原因。

std::string Hexlify(const std::string& iData)
{
    // the same as python binascii.b2a_hex
    const size_t len = iData.size() << 1; // output will be twice as long
    std::vector<char> hex(len);
    const char* curdata = iData.data();
    char* curhex = &hex[0];
    const char* end = curdata + iData.size();
    // SAME CODE AS BEFORE
    return std::string(&hex[0], len);
}

std::vector实现生成 Valgrind 的"大小为 1 的无效写入"错误。

知道为什么吗?

如果我将hex向量增大两个字节(一个似乎还不够)

std::vector<char> hex(len + 2);

该错误从瓦尔格林德的报告中消失了。

因为你出局了一个。

如果iData说"xy",那么end指向"y"后面的一个。使用您的<= end,您尝试将 3 个字符(给出 6 个十六进制数字)编码到一个仅足够容纳 4 的空格中。

您的问题是end的一个错误。 您可以通过在C++中使用一些更高级别的概念来避免这种棘手的边缘情况,而不会降低运行时速度。 特别是,基于范围的for和使用std::string作为标准容器意味着我们可以在没有边界测试或指针算法的情况下实现这一点:

#include <string>
std::string hexlify(const std::string& s)
{
    static auto const to_hex = [](char c)
        {
            c &= 0xf; return c>9 ? c+'a'-10 : c+'0';
        };
    std::string result;
    result.reserve(2 * s.size());
    for (auto b: s) {
        result.push_back(to_hex(b>>4));
        result.push_back(to_hex(b));
    }
    return result;
}

int main()
{
    static auto const test = [](const std::string& in,
                                const std::string& expected)
        {
            return hexlify(in) != expected;
        };
    // We use numeric character escapes to avoid dependence on any
    // specific character coding.
    return test("60", "30")
        +  test({"", 1}, "00")
        +  test({"", 2}, "0000")
        +  test("377", "ff");
}

那是瓦尔格林德干净的。

相关内容

  • 没有找到相关文章

最新更新