在 sscanf() 之后调用 free() 时检测到堆损坏



我正在尝试编写一个函数来将十六进制值字符串转换为字节数组。这段代码有什么问题?

调用free()后,我收到错误"检测到堆损坏"。如果我评论对sscanf的调用,一切正常。sscanf 是否写入超出 malloc 分配的内存的内容?

unsigned char* hextobytes(const string& hex) {
    size_t size = hex.size() / 2;
    unsigned char* bytes = (unsigned char*)malloc(size);
    const string::value_type* pos = hex.c_str();
    for (size_t c = 0; c < size; c++) {
        sscanf((pos + 2 * c), "%2hhx", bytes + c);
    }
    return bytes;
}
int _tmain(int argc, _TCHAR* argv[]) {
    string hex = "FFFF";
    unsigned char* bytes = hextobytes(hex);
    free(bytes);
    return 0;
}

更新:我正在开发Visual Sudio 2013

我在这里找到了答案。

Microsoft版本的 scanf 不支持长度修饰符"hh"来指定无符号字符。它支持指定短整型的修饰符"h"。

使用短 int 数组而不是无符号字符解决了我的问题。

你的源代码的主要问题是它是C++的,但编程是非常 C 风格。

其他人指出,发布的代码不会显示您声称的错误。

但是,如果可以的话,请允许我展示如何C++风格完成此操作,没有任何堆损坏的机会,因为C++为我们提供了避免"裸"指针所需的所有工具:

#include <string>
#include <vector>
#include <iostream>
std::vector< unsigned char > hextobytes( const std::string & hex )
{
    std::vector< unsigned char > rc;
    for ( size_t i = 0; i < hex.size(); i += 2 )
    {
        // this may throw std::invalid_argument if no
        // conversion can be performed
        // formally std::out_of_range would be also a
        // possibility, but not with a two-digit hex...
        rc.push_back( static_cast< unsigned char >(
            std::stoul( hex.substr( i, 2 ), 0, 16 ) )
        );
    }
    return rc;
}
int main()
{
    std::string hex( "FFFF" );
    std::vector< unsigned char > bytes = hextobytes( hex );
    for ( auto a : bytes )
    {
        std::cout << static_cast< int >( a ) << "n";
    }
    return 0;
}

最新更新