2012年5月31日星期四

一个空string引发的血案

这确实是一个血案啊。linux下跑程序,由于是通过脚本来调用程序,结果程序崩溃时没看到通常的segment fault,只有崩溃前的log。然后仔细看了一下代码,很容易就发现问题所在。
代码是这样的:
1 string send_charac_name_org = "aa";
2 string send_charac_name = testfunc((char*)send_charac_name.c_str());
其实就是一个笔误,两处红色的地方不一致导致的。不过本着刻苦钻研的精神,我还是仔细研究了一下。

  1. 首先,程序为什么崩溃,在testfunc里面打印,发现传进去的参数是一个0地址,所以必然崩溃了。
  2. c_str()是返回string变量的一个指针,在sgi版本的stl里面,这个指针_M_start指向string变量的首字符。那就是说这个指针是0,才导致的崩溃了。c_str()通常返回的是const char*,这里强制变为char *。
  3. 按理说定义了一个变量后,应该会分配内存,string里面的指针应该不为空的。说明这种写法 send_charac_name 还处于声明结束,没有定义完成啊。所以我换了个写法:
    string  send_charac_name ;
    send_charac_name =testfunc((char*)send_charac_name.c_str());
    这样就不会出现0地址了,说明string变量已经分配完内存了。
    为了进一步搞清楚,又把stl的代码拿来看了一下,string的基类初始化时是没有分配内存的,只是把_M_start,_M_finish,_M_end_of_storage三个指针置为0了,只有到分配内存的时候才回设置三个指针。string变量定义完成后,sgi的版本是默认分配了8个字节的内存的。

这样看来,这个问题其实很简单,但是今天花时间主要是在看stl的代码上面,从研究生做完项目以后,我就没看到stl代码了,今天看了好一阵,太费劲了。每次看stl源码都有点生不如死的感觉啊。


没有评论:

发表评论