使用_snscanf_s转换十六进制时引起的内存越界
//将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转换十六进制时引起的内存越界的更多相关文章
- C++使用继承时子对象的内存布局
C++使用继承时子对象的内存布局 // */ // ]]> C++使用继承时子对象的内存布局 Table of Contents 1 示例程序 2 对象的内存布局 1 示例程序 class ...
- PHP 将秒数转换成时分秒
将秒数转换成时分秒,PHP提供了一个函数gmstrftime,不过该函数仅限于24小时内的秒数转换.对于超过24小时的秒数,我们应该怎么让其显示出来呢,例如 34:02:02 $seconds = 3 ...
- eclipse启动时虚拟机初始内存配置
eclipse启动时虚拟机初始内存配置: -Xms256M -Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m
- PowerDesigner中转换物理模型时的命名转换
原文:PowerDesigner中转换物理模型时的命名转换 最近在使用PowerDesigner建模数据库,在使用中积累了一些遇到的问题和解决办法,记录下来,希望对遇到同样问题的朋友有所帮助. 早 期 ...
- C++ 类T T t;构造时分配的内存在静态数据区 T t=new T()分配的内存在堆 这样说对吗
C++ 类T T t;构造时分配的内存在静态数据区 T t=new T()分配的内存在堆
- <!--转换office时需要此配置 --> <identity impersonate="true" />
1.需要对Office 进行操作时 ,添加权限 <!--转换office时需要此配置 --> <identity impersonate="true" /> ...
- 使用C++做算法时,对内存的管理的办法
使用C++做算法时,对内存的管理的办法 最近老是在想C++的内存控制机制,查了一些资料所以有点想法,自己记录一下免得以后自己忘了. 1. 需求 在做线性代数的算法时,首要的就实现Matrix这个类.由 ...
- spring boot @ResponseBody转换JSON 时 Date 类型处理方法,Jackson和FastJson两种方式,springboot 2.0.9配置fastjson不生效官方解决办法
spring boot @ResponseBody转换JSON 时 Date 类型处理方法 ,这里一共有两种不同解析方式(Jackson和FastJson两种方式,springboot我用的1.x的版 ...
- 三:C#对象转换Json时的一些高级(特殊)设置;
导航目录: Newtonsoft.Json 概述 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型: 二:C#对象.集合.DataTable与Json内容互转示例: ...
随机推荐
- Jeecg 如何执行批量insert或者update操作,高效率
方法:org.jeecgframework.core.common.dao.jdbc.SimpleJdbcTemplate.batchUpdate 原理: 基于springjdbc封装,批量提 ...
- 执行 update操作的时候有报错 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> show full processlist; #查看问题的线程!!!! 找到异常进程的ID 然后kill 掉: mysql> kill xxxxxxx; #xxxxxx是ID ...
- Disk performance
http://blogs.msdn.com/b/ntdebugging/archive/2014/12/09/disk-performance-internals.aspx http://blogs. ...
- jvisualvm工具使用
VisualVM 是Netbeans的profile子项目,已在JDK6.0 update 7 中自带(java启动时不需要特定参数,监控工具在bin/jvisualvm.exe). https:// ...
- ~function(){}() 和(function(){}){}
使用~function(){}()也是声明并调用函数的方法之一: 这是一段使用~function(){}()来声明函数并调用函数的例子: ~function() { alert(typeof next ...
- 【转】32位和64位系统区别及int字节数
http://blog.csdn.net/zhongzhiwei/article/details/8678885 一)64位系统和32位有什么区别? 1.64bit CPU拥有更大的寻址能力,最大支持 ...
- nyoj 715 Adjacent Bit Counts
描述 For a string of n bits x1, x2, x3, …, xn, the adjacent bit count of the string is given by ...
- feginclient demo
1.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...
- SQLSERVER 子查询中使用ORDER BY
SQLSERVER如何在子查询中使用ORDER BY 今天在使用公司的一个pager接口的时候,需要传递一个查询的SQL语句,因为我希望他能够在pager对他查询出来的结果排序之前自己先进行排序, 于 ...
- JAVA培训资料
JAVA培训资料 一.Java语言 1.面向对象的三个基本特征 2.方法重载和方法重写的概念和区别 3.接口和内部类.抽象类的特性 4.文件读写的基本类 **5.串行化的注意事项以及如何实现串行化 6 ...