我有将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错误......我做错了什么?
答案 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]);
正如其他人所说,无论如何,这是实现这个功能的一种非常糟糕的方式。