【问题标题】:HEAP CORRUPTION DETECTED when calling free() after sscanf()在 sscanf() 之后调用 free() 时检测到堆损坏
【发布时间】:2016-02-19 11:43:01
【问题描述】:

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

调用 free() 后,我收到错误 HEAP CORRUPTION DETECTED。如果我评论对 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

【问题讨论】:

  • 不要在 C++ 中使用 malloc,使用 new(并尽量避免显式使用它:阅读智能指针和容器)
  • 嗯....这是非常多的C,我必须很难看到它的C++部分...
  • @DevSolar 仔细看,它就在那里,在 for 循环的第三个表达式中:)
  • @Lundin:他正在转换malloc() 的返回值,是一个死的赠品。 :) {我是一个 baaaaad 人...}
  • 这段代码没有错误。请记住,堆损坏通常是在损坏完成很久之后才报告的,而且通常不是由进行分配的代码引起的。

标签: c++ c


【解决方案1】:

我找到了答案here

Microsoft 版本的 scanf 不支持使用长度修饰符“hh”来指定无符号字符。它支持指定短整数的修饰符“h”。

使用 short int 数组而不是 unsigned char 可以解决我的问题。

【讨论】:

  • 不幸的是,Microsoft 的政策是不真正打扰他们编译器的 C 功能的持续更新。放弃 C 风格并采用正确的 C++ 习惯用法的另一个理由。
  • @DevSolar 虽然它不能解决实际问题,但我会保留 C++ 样式示例的解决方案,谢谢
  • 好吧,这取决于您如何定义“实际问题”。 ;-) 我认为 C++ 环境中的 C 风格编码,尤其是裸指针和数组的使用,是一个问题;仅仅是因为在适当的 C++ 中根本不会出现这么多问题。 (当然,它有其自己的问题集合,但你明白我来自哪里。);-)
【解决方案2】:

您的源代码的主要问题是它是 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-02
    • 2013-10-12
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多