为什么我在此示例代码中有HEAP CORRUPTION?

时间:2014-01-09 09:32:39

标签: c++ memory-management heap-corruption

我有将Hex String转换为Byte Array的函数,

BYTE* HexStrToByteArray(std::wstring hex_str)
{
    int len = hex_str.size()*0.5f;
    BYTE *bytearray = new BYTE[len];
    for(int i = 0; i < len; i++) 
    {
        swscanf(hex_str.c_str() + 2*i, L"%02x", &bytearray[i]);
    }
    return bytearray;
}

在代码中我像这样使用它

BYTE *byte_array = HexStrToByteArray(hex_str);

现在函数工作正常,但是当我尝试释放内存时,在函数中分配

delete [] byte_array;//HEAP CORUPTION ERROR

我有HEAP CORUPTION错误......我做错了什么?

3 个答案:

答案 0 :(得分:4)

在代码上运行valgrind会很快显示问题:

Invalid write of size 4
==34783==    by 0x21B719: swscanf
Address 0x100004000 is 0 bytes inside a block of size 3 alloc'd

当我在长度为6的十六进制字符串上运行代码时出现此错误:

BYTE *ba = HexStrToByteArray(L"123456");

当然,这应该产生3个字节。但是,%02x转换说明符使swscanf()期望指向unsigned int(在您的实现上恰好是4个字节长),而您传递的是BYTE *,这可能是指向unsigned char的指针。


使用scanf()而不是试图弄乱strtoul(),这是可怕的。另外,使用std::size_t表示大小,请不要使用浮点数污染整数运算。此外,如果您的十六进制字符串是奇数个字符,则需要为它分配一个额外的字节。另外,我建议你通过const引用传递输入字符串,以避免不必要的副本。

BYTE *HexStrToByteArray(const std::wstring &hex_str)
{
    std::size_t len = (hex_str.size() + 1) / 2;
    char buf[3] = { 0 };
    BYTE *bytearray = new BYTE[len];

    for (std::size_t i = 0; i < len; i++) {
        buf[0] = hex_str[2 * i + 0];
        buf[1] = hex_str[2 * i + 1];
        bytearray[i] = std::strtoul(buf, NULL, 16);
    }

    return bytearray;
}

答案 1 :(得分:3)

"%02x"格式规范要求写入unsigned int值,因此不是在每次循环迭代中写入单个字节,而是写入4个字节。

所以你要写完所分配的bytearray

答案 2 :(得分:1)

您只是为swscanf使用了错误的格式说明符,因此为每个十六进制对写入四个字节。使用hh参数类型修饰符。 http://en.cppreference.com/w/c/io/fscanf

试试这个。

swscanf(hex_str.c_str() + 2*i, L"%02hhx", &bytearray[i]);

正如其他人所说,无论如何,这是实现这个功能的一种非常糟糕的方式。