/////////////////////////////////// //author : zhxfl //date : 2013.4.9 //email : [email protected] //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的深拷贝,可惜拷贝的地址已经失效了。
时间: 2024-12-09 13:21:32