zoukankan      html  css  js  c++  java
  • 用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看来要作出特殊处理才行了.

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

  • 相关阅读:
    Todo
    我的类
    Python socket编程之七:多窗口的应用
    iOS与PHP/Android AES128 ECB NoPadding加密
    JSONModel简便应用
    iOS开发系列--UITableView全面解析
    常用方法
    OC和C++混编
    数据层
    block
  • 原文地址:https://www.cnblogs.com/vimmer/p/2617549.html
Copyright © 2011-2022 走看看