//将Hex编码转换为指定编码格式的字符串
string Encoding::DecodeHexString(const string &strSrc, UINT code_page )
{
string::size_type length = strSrc.length() / ;
char *result = new char[length + ];
ZeroMemory(result, length + );
const char* str = strSrc.c_str();
for(string::size_type i = ; i < length; ++i)
{
_snscanf_s(str + (i * ), , "%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() / ;
char *result = new char[length + ];
ZeroMemory(result, length + );
const char* str = strSrc.c_str();
int value = ; for(string::size_type i = ; i < length; ++i)
{
_snscanf_s(str + (i * ), , "%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字节)。

使用_snscanf_s转换十六进制时引起的内存越界的更多相关文章

  1. C++使用继承时子对象的内存布局

    C++使用继承时子对象的内存布局 // */ // ]]>   C++使用继承时子对象的内存布局 Table of Contents 1 示例程序 2 对象的内存布局 1 示例程序 class ...

  2. PHP 将秒数转换成时分秒

    将秒数转换成时分秒,PHP提供了一个函数gmstrftime,不过该函数仅限于24小时内的秒数转换.对于超过24小时的秒数,我们应该怎么让其显示出来呢,例如 34:02:02 $seconds = 3 ...

  3. eclipse启动时虚拟机初始内存配置

    eclipse启动时虚拟机初始内存配置: -Xms256M -Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m

  4. PowerDesigner中转换物理模型时的命名转换

    原文:PowerDesigner中转换物理模型时的命名转换 最近在使用PowerDesigner建模数据库,在使用中积累了一些遇到的问题和解决办法,记录下来,希望对遇到同样问题的朋友有所帮助. 早 期 ...

  5. C++ 类T T t;构造时分配的内存在静态数据区 T t=new T()分配的内存在堆 这样说对吗

    C++  类T   T t;构造时分配的内存在静态数据区   T t=new T()分配的内存在堆

  6. <!--转换office时需要此配置 --> <identity impersonate="true" />

    1.需要对Office 进行操作时 ,添加权限  <!--转换office时需要此配置 --> <identity impersonate="true" /> ...

  7. 使用C++做算法时,对内存的管理的办法

    使用C++做算法时,对内存的管理的办法 最近老是在想C++的内存控制机制,查了一些资料所以有点想法,自己记录一下免得以后自己忘了. 1. 需求 在做线性代数的算法时,首要的就实现Matrix这个类.由 ...

  8. spring boot @ResponseBody转换JSON 时 Date 类型处理方法,Jackson和FastJson两种方式,springboot 2.0.9配置fastjson不生效官方解决办法

    spring boot @ResponseBody转换JSON 时 Date 类型处理方法 ,这里一共有两种不同解析方式(Jackson和FastJson两种方式,springboot我用的1.x的版 ...

  9. 三:C#对象转换Json时的一些高级(特殊)设置;

    导航目录: Newtonsoft.Json 概述 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型:    二:C#对象.集合.DataTable与Json内容互转示例: ...

随机推荐

  1. Python学习手冊笔记

    之前为了编写一个svm分词的程序而简单学了下Python.认为Python非常好用.想深入并系统学习一下,了解一些机制,因此開始阅读<Python学习手冊(第三版)>. 假设仅仅是想高速入 ...

  2. UVa 12715 Watching the Kangaroo(二分)

    题意:n条线段(n <= 100000) (L<=R <= 1e9) ,m组询问(m <= 100000) 每次询问一个点的覆盖范围的最大值.一个点x对于一条包括其的线段,覆盖 ...

  3. 【Android】10.5 滚动视图(RecyclerView)

    分类:C#.Android.VS2015: 创建日期:2016-02-19 一.简介 滚动视图(RecyclerView)的用法与布局控件的用法类似,唯一不同的是,所有布局控件中都可以包含多个组件,而 ...

  4. 149. Best Time to Buy and Sell Stock【medium】

    Say you have an array for which the ith element is the price of a given stock on day i. If you were ...

  5. Solr学习之五

    一.段管理 段是一个自包含,仅可读的solr的索引的子集.一旦一个段被刷新到持久存储后,它将不会改变.当添加新文档到你的索引时候,它们被写入到新的段中.因此,在你的索引中,有很多激活的段.一次查询必须 ...

  6. QT 4.8 静态库编译方法

    最最初踏上QT之路是受到了XiaomaGee的指点,相比于常规的窗口程序开发,QT有着以下特点: 1. 优良的跨平台特性(支持Win.Linux.Mac 不同的平台下只需重新编译即可使用) 2. 面向 ...

  7. vue实现复制粘贴的两种形式

    方式一: 1.安装clipboard:npm install clipboard 2.src/utils/clipboard.js import Vue from 'vue' import Clipb ...

  8. jacky自问自答-java并发编程

    1.java Web中线程不是由tomcat这类web容器负责的吗?为什么还要我控制多线程? 答:这个问题很多初学者都会有的疑惑,举一个我以前做的一个需求,java作为中间平台,是socket服务端, ...

  9. Java中HashMap实现原理

    类声明: 概述: 线程不安全: <Key, Value>两者都可以为null: 不保证映射的顺序,特别是它不保证该顺序恒久不变: HashMap使用Iterator: HashMap中ha ...

  10. C语言 · 整除问题

    算法训练 整除问题   时间限制:1.0s   内存限制:512.0MB      问题描述 编写一个程序,输入三个正整数min.max和factor,然后对于min到max之间的每一个整数(包括mi ...