首页 > 代码库 > crash日记-- C++ 危险的c_str()

crash日记-- C++ 危险的c_str()

/////////////////////////////////////author : zhxfl//date   : 2013.4.9//email  : 291221622@qq.com//Adress : http://blog.sina.com.cn/s/blog_a502f1a30101jqtp.html///////////////////////////////////#include <iostream>#include <cstdio>using namespace std;const std::string& fun(){    string s = "myFuntion";    return s.c_str();}int main(){    string s = fun();    printf("%s",s.c_str());    return true;}

 

1 c_str()是临时变量
这是我们项目中出现的一个代码,这是一个不一定崩溃的代码,这种错误可能是无意的,不错找起来就不好找了。可以先在这里说明原因,string的c_str()是一个临时变量,fun结束的时候,他是会被“清除”(实际上没有清除)掉的。也就是return s.c_str()返回的是一个无效的指针。
 
2 函数return的时候是先释放临时变量还是先做返回值复制。
    小标题有点2B啦,弄点悬念技术分享
    很显然,上述已经完整的说明的错误的主要原因,写到这里如果完了的话,这篇blog也就没有什么意义了,作 为程序员的我,还是想深入了解一个问题(如小标题)。fun在return的时候虽然是一个临时变量,但是fun的参数是string,应该会做了一次深 拷贝了,按照这样说,这个是不会出问题的(事实也是在window不出问题,用jni在android上才出现了必崩的现象)。现在我们就来回答这个问 题。
    这里假设你已经搞清楚堆和栈的区别了。
    这里所有东西都跟函数调用过程的栈管理有关。
    1)在进入函数的时候,先把函数返回地址压入栈中(函数结束的时候就根据这个回到调用函数的地方,可以理解吧),接着程序会申请足够用的栈空间.
    2)对于c_str()变量,是放在栈里面的临时变量,函数运行结束,栈空间被回收(如果你懂一点汇编,应该会知道栈是回收其实就是ebp变小而已)。函数的返回参数是放在eax里面的。这时候回到了调用函数的地方,在根据目前的eax做一次string的深拷贝,可惜拷贝的地址已经失效了。
 

crash日记-- C++ 危险的c_str()