前两天测试一段代码,大致如下(和实际代码有出入,这里只做模拟):
#include <string>
#include <stdio.h>
using namespace std;
int main(int argc, char* argv[])
{
string str_test1 = "123";
const char* str_test2 = "567";
str_test1 += str_test2 + '4';
printf("str_test1 value is %s./n", str_test1.c_str());
return 0;
}
期待的结果是:str_test1 value is 1235674.
运行发现,结果却是:str_test1 value is 123esp.c.
哪里出问题了呢?
大家知道,string 操作=运算符运算时,如果右参数为char*,string会先以char*参数为输入逐字符进行push,那么str_test2追加’4’后地址是否有变化呢?
进行测试:
string str_test1 = "123";
char* str_test2 = "567";
printf("before add, address of str_test2 is %p./n", str_test2);
str_test1 += str_test2 + '4';
printf("after add, address of str_test2 is %p./n", str_test2 + '4');
printf("str_test1 value is %s./n", str_test1.c_str());
return 0;
结果如下:
//before add, address of str_test2 is 004240A0.
//after add, address of str_test2 is 004240D4.
很明显,前后str_test2地址不等,相差52,考虑到’4’的ascii码数值表示恰好为52,一切真相大白了:
str_test1进行+=操作时,是以str_test2+52地址开始处的字符进行追加的,导致出问题,如果str_test2为string类型,则会先以char参数为输入构造string(实际为basic_string类型),而后追加,如下:
…
typedef basic_string<_CharT,_Traits,_Alloc> _Str;
typedef typename _Str::_Reserve_t _Reserve_t;
const size_t __n = _Traits::length(__s);
# ifdef _STLP_INIT_AMBIGUITY
_Str __result = _Str(_Reserve_t(), __n + __y.size());
# else
_Str __result(_Reserve_t(), __n + __y.size());
# endif
__result.append(__s, __s + __n);
__result.append(__y);
return __result;
…
注:
上述模拟程序将’4’修改为”4”后依然有问题,会报:
error C2110: cannot add two pointers(VC 6.0)
需将+操作符两边参数任一个改为string类型