int向string赋值潜在的溢出bug
来源:互联网 发布:淘宝店铺护肤品简介 编辑:程序博客网 时间:2024/05/16 08:46
2011-11-1 wcdj
在程序中,有时会这样写代码:
#define XXX_ID 1string str_result;str_result = XXX_ID;// ...int iResultCode = atoi(str_result.c_str());问题:这样的代码是否正确?
程序员本意的想法是iResultCode 应该为 1:
// errorstr = 1; int iRes = atoi(str.c_str());// iRes == 1 ? , wrong! iRes == 0
实际的情况:
str = 数字,编译器会把这个数字解释为一个字符的ASCII值,从而把这个字符通过重载赋值运算符函数,赋值给str这个对象。因此,当str = 49; 时,str被赋值为字符 '1' 。然后,再通过atoi转换,iRes的值也为1。
// okstr = 49; int iRes = atoi(str.c_str());// iRes == 1, ok
原因分析:
string str;str = 1;会调用:_Myt& operator=(_Elem _Ch)// _Ch == 1{// assign 1 * _Chreturn (assign(1, _Ch));}str = '1';会调用:_Myt& operator=(_Elem _Ch)// _Ch == 49{// assign 1 * _Chreturn (assign(1, _Ch));}str = "1";会调用:_Myt& operator=(const _Elem *_Ptr){// assign [_Ptr, <null>)return (assign(_Ptr));}一个存在bug的例子:
#include <iostream>#include <string>using std::string;using namespace std;int main(int argc, char* argv[]){string str1, str2, str3, str4;str1 = "1";str2 = '1'; /*str = (char)0;// 0str = 1;// 1str = 127;// 127str = 128;// -128 str = 255;// -1str = 256;// 0str = 257;// 1*/// warning C4305: 'argument' : truncation from 'int' to 'char'// warning C4309: 'argument' : truncation of constant valuestr3 = 257;str4 = 1;// ok, no warningif (str3 == str4){cout << "bug" <<endl;}cout << str1.c_str() << endl;cout << str2.c_str() <<endl;cout << str3.c_str() <<endl;cout << str4.c_str() <<endl; return 0;}
结论:
用一个常量向string赋值的时候,这个常量的最大有效范围是char,即,0~127,超过这个范围就会被截断,而且用常量向string赋值然后再atoi转换回来,这个结果也是与我们的意愿不符的,并不会返回正确的值。因此,安全的做法应该是:先将int转换为char*,再赋值给string,这样我们想保存的最大数值(ID)可以为最大整型类型所表示的最大数值。
char szTmp[128]={0};sprintf(szTmp, "%d", 257);str3 = szTmp;memset(szTmp, 0 ,sizeof(szTmp));sprintf(szTmp, "%d", 1);str3 = szTmp;
安全一点的做法是使用:snprintf(Linux)/ _snprintf(Windows)。
const int iLen = 128;char szTmp[iLen] = {0};_snprintf(szTmp, sizeof(szTmp)-1, "%d", 257);str3 = szTmp;memset(szTmp, 0 ,sizeof(szTmp));_snprintf(szTmp, sizeof(szTmp)-1, "%d", 1);str3 = szTmp;
注意:snprintf(Linux)与 _snprintf(Windows)对补0有不同,Linux下的自动补0,Windows的则不会。
- int向string赋值潜在的溢出bug
- iTween的一个潜在BUG
- linux下实现string向int的转换
- int溢出的问题
- UITextField中secureTextEntry的潜在BUG
- java.lang.Integer cannot be cast to java.lang.String Java int,double向String的转化和String向int,double的转换
- java.lang.Integer cannot be cast to java.lang.String Java int,double向String的转化和String向int,double的转换
- 一个潜在类型溢出
- Java int 类型向String转换
- 注意int溢出的情况
- 一个栈溢出的BUG
- ulua整数溢出的BUG
- String 赋值 的漏洞
- MDK赋值出错的BUG
- java int, double 向 String 转换, String 向 int ,double 转换
- cocos2d-x touches事件中使用 addTargetedDelegate 的潜在bug
- VS2005 Debug版,dll /MTd,exe /MDd的潜在bug
- 使用代码检查工具解决C++潜在的bug
- 实现DropDownList 无刷新的联动效果
- winscp连接vmware ubuntu
- MySQL事件调度器详解
- Android 镜像倒影特效Gallery
- 100之内素数
- int向string赋值潜在的溢出bug
- Thread、Looper、Handler和Message
- javascript 学习笔记(三)
- oracle pctfree与pctused
- AHB总线之总结一
- JavaScript对象转换成JSON字符串及深度克隆方法
- linux flash插件安装
- Android树控件
- 在共享DLL中使用MFC 和在静态库中使用MFC