zoukankan      html  css  js  c++  java
  • 使用_snscanf_s转换十六进制时引起的内存越界

    //将Hex编码转换为指定编码格式的字符串
    string Encoding::DecodeHexString(const string &strSrc, UINT code_page )
    {
        string::size_type length = strSrc.length() / 2;
        char *result = new char[length + 1];
        ZeroMemory(result, length + 1);
        const char* str = strSrc.c_str();
        for(string::size_type i = 0; i < length; ++i)
        {
            _snscanf_s(str + (i * 2), 2, "%X", &result[i]);
        }
    
        string str = ConvertTo((char*)result, code_page);
        delete[] result;
    
        return str;
    }

      此函数中,传入strtSrc参数是一个经过十六进制编码的字符串,此函数将每两个十六进制字符转换成一个十进制数,然后再转换未指定编码格式的字符串。

      从逻辑上看,这段代码没什么问题。但是程序运行到delete[] result;语句时就会出错,无法删除数组。

      因为经验不足,当时怎么想都没想明白。花了好几个小时调试才发现问题所在。

      _snscanf_s每次都往result写入4个字节(int),而result每个元素都是1字节,这就相当于一次写入了4个char。我的原意是每次输入一个1字节的十进制数。

      这就导致最后数组长度增加了3个字节,也就是发生了内存越界。delete操作也就出错了。

      修改后正确的代码应该是这样:

    //将Hex编码转换为指定编码格式的字符串
    string Encoding::DecodeHexString(const string &strSrc, UINT code_page )
    {
        string::size_type length = strSrc.length() / 2;
        char *result = new char[length + 1];
        ZeroMemory(result, length + 1);
        const char* str = strSrc.c_str();
        int value = 0;
        
        for(string::size_type i = 0; i < length; ++i)
        {
            _snscanf_s(str + (i * 2), 2, "%X", &value);
            result[i] = value;
        }
    
        string str= ConvertTo((char*)result, code_page);
        delete[] result;
    
        return str;
    }

      用一个4字节的int类型变量来接收输出参数,再赋值给result数组就可以了。int赋值给char这样做不就会发生截断吗?那么数据不就失真了么?

      是的,这样做会发生截断,但是不会失真。

      因为将字节流Hex编码的字符串时,每一个字节表示的数都会转换为unsigned char(1字节), 所以解码Hex字符串时所得到的数不可能超过255(1字节)。

  • 相关阅读:
    如何理解显示卡的驱动模块(DDX,DRM,DRI,XVMC)
    基于Linux的嵌入式文件系统构建与设计
    Windows系统——后缀为.zip.00X的zip分卷解压
    windows系统——U 盘损坏修复
    windows系统——常用命令
    U盘用FAT32还是用NTFS格式好
    linux系统程序设计教程
    Posix线程编程指南
    编程风格——UNIX 高手的 10 个习惯
    linux压缩文件——解压方法
  • 原文地址:https://www.cnblogs.com/dvwei/p/3543041.html
Copyright © 2011-2022 走看看