用NULL来构造string会出问题

最近某应用跑压力测试的时候出现了下面的错

 

[2012-07-31 22:33:59:271046, db_mgr.cpp:GetDeviceInfo:1129, DBG , 0xb35f4b90]: select object_id, object_name, object_type_id, class_type_id, device_type_id from m_object where object_id = 225663102
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct NULL not valid

 

首先我对

terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct NULL not valid

这个报错信息是陌生的....

 

所以我直接到文件

db_mgr.cpp:GetDeviceInfo:1129去定位错误,并没太多收获,文件的内容为

  g_log.LogTextEx(DBG, "%s", oss.str().c_str());   

 

我只能间接查出设备  225663102 所属的基站,

发现里面还没有基础信息的xml文件中,所以进一步缩窄范围.

所以基本定义到了GetDeviceInfo的调用者  XMLMaker::GenBaseInfo 中了

 

再根据出错的提示,网上说这个出错信息是用空指针去构造string会出问题,

有下面类似的说明

http://gcoder.blogbus.com/logs/32262907.html

std::string 的初始化碰到一个问题, 拿一个 char* 的指针当构造函数的指针, 运行时出现:

terminate called after throwing an instance of 'std::logic_error'
 what():  basic_string::_S_construct NULL not valid

已放弃

原因在于没搞清, char *型的变量和指向 c 风格的字符串指针的区别.

char *cp = NULL;     cp是一个char*变量

char *str = "Hello";  str是一个指向 c 风格的字符串指针.

std::string 的构造函数需要的是一个 c 风格的字符串指针(要求以字符 null 结尾), 而不是一个char *的变量. 所以运行时出了上述错误.

另外, 很多 c 标准函数, 函数明确说明, 需要一个 c 风格的字符串. 虽然char * 和指向 c 风格的字符串指针的代码看起来都是 char *, 但是含义上有本质的区别.

 

所以为此,我特意在开发机上写下如下的测试代码

 

 

 1  #include <string>                              
 2  #include <iostream>                            
 3                                                 
 4  using std::string;                             
 5                                                 
 6                                                 
 7  int main(int argc, const char *argv[])         
 8  {                                              
 9          string str = NULL;                     
10          std::cout << str << std::endl;         
11          return 0;                              
12  }                                              

compile没问题,运行时确报错

:!a.out
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct NULL not valid

Command terminated

 

这个报出来的错误信息基本上与我之前应用的相似的,

信息足够定位了,于是我就在方法

XMLMaker::GenBaseInfo中打一些string 的构造

发现了如下关于转码的一句.

1   string str_tmp = g2u(const_cast<char*>(di.object_name.c_str()));   
2   xmlNewChild(node_lv2, NULL, BAD_CAST "object_name",                
3                   BAD_CAST str_tmp.c_str());                         

而再追到

 1 //GB2312码转为UNICODE码                                                         
 2 //成功则返回一个动态分配的char*变量,需要在使用完毕后手动free,失败返回NULL     
 3 char* g2u(char *inbuf)                                                               
 4 {                                                                               
 5         int nOutLen = 2 * strlen(inbuf) - 1;                                    
 6         char* szOut = (char*)malloc(nOutLen);                                   
 7                                                                                 
 8         if (-1 == code_convert("gb2312","utf-8",inbuf,strlen(inbuf),szOut,nOutLen))
 9         {                                                                       
10                 free(szOut);                                                    
11                 szOut = NULL;                                                   
12         }                                                                       
13         return szOut;                                                           
14 }                                                                                    
15                                                                                      

发现从其它地方挪过来的代码居然会返回NULL看来要作出特殊处理才行了.

 

这样,这个问题就基本定位,剩下就是修改并回归测试了

posted on 2012-07-31 23:18  Orz..  阅读(2580)  评论(0编辑  收藏  举报

导航