我们知道,string类为我们提供了很多的便利,我们用string类能方便的做字符串的各种操作,避免了我们直接操作char指针而产生的一些繁琐的操作,和内存泄露的可能性,可是string类也是有陷阱的。下面我们看这样一个例子,你能看出问题所在吗?

string getString()
{
return "just a test";
}
void test()
{
const char *pc = getString().c_str();
cout<<pc<<endl;
}

如果看不出来可以实际运行一下,会发现输不出结果来,这是为什么呢?

当我们写getString函数时,如果其返回类型是const char*我们可能会分外小心,因为我们知道"just a test"生命会在函数返回后结束,我们可能会new一段空间来放这个字符串,然后返回指针,或者是要求调用者给一个空间来放这个字符串。但是当返回类型是string时,我们就不会如此小心翼翼,因为我们知道string类实现了拷贝构造函数和赋值函数。它会为我们操心空间分配和销毁的问题。所以在这里,我们直接返回"just a test"字符串是没有问题的。

接着我们对一个string对象调用c_str函数貌似也没有什么问题,因为这是string类提供给我们的功能。但是这里的关键是,我们没有将getString()的结果赋给一个string对象就直接获取其指针了,这时,系统并不会为string调用拷贝构造函数或是赋值函数,返回的string仍然只是一个临时对象的状态,它会在完成对pc的赋值后被销毁,这时其内部的数据也不会存在了。

怎么解决这个问题呢?

我们要改变c_str函数,让它不要直接返回指针,而是new一段空间来放这个字符串再返回指针吗?这样,会降低效率,且每个调用c_str函数的用户都需要操心delete指针的问题,很容易造成内存泄露。

我们要改写getString函数,重新为返回的字符串new一段空间吗?这么做显然也不合适。

这时,我们有两种比较可行的解决方法。

1.不要直接返回临时对象的指针,将临时对象先赋值给一个局部对象,再获取其指针。这样,将上例改写为

void test()
{
string str = getString();
const char *pc = str.c_str();
cout<<pc<<endl;
}

2.如果要使用临时对象的指针,将所有的使用放到一个语句里进行。这样,将上例改写为

void test()
{
cout<<getString().c_str()<<endl;
}

上面是个人愚见,欢迎大家讨论!

C++陷阱之慎用string类的更多相关文章

  1. java中的String类常量池详解

    test1: package StringTest; public class test1 { /** * @param args */ public static void main(String[ ...

  2. 跟着刚哥梳理java知识点——深入理解String类(九)

    一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...

  3. java之String类在堆栈存储机制

    String类是一个比较特殊的类,最主要的体现是它有多种创建形式,例如,String a ="abc";Sting a=new("abc");表面上看得到的结果 ...

  4. STL 的string类怎么啦?

    前言   上个周末在和我的同学爬香山闲聊时,同学说到STL中的string类曾经让他备受折磨,几年前他开发一个系统前对string类还比较清楚,然后随着程序的复杂度的加深,到了后期,他几乎对strin ...

  5. String类的详细

    String str = new String("abc")创建过程 (1) 先定义一个名为str的对String类的对象引用变量放入栈中. (2) 然后在堆中(不是常量池)创建一 ...

  6. Java之String类用法总结

    String类概述: 1.String类代表字符串.Java 程序中的所有字符串字面值(如"abc")都作为此类的实例实现. 2.String是一个final类,代表不可变的字符序 ...

  7. 标准库String类

    下面的程序并没有把String类的所有成员方法实现,只参考教程写了大部分重要的成员函数. [cpp] view plain copy #include<iostream> #include ...

  8. 自己实现简单的string类

    1.前言 最近看了下<C++Primer>,觉得受益匪浅.不过纸上得来终觉浅,觉知此事须躬行.今天看了类类型,书中简单实现了String类,自己以前也学过C++,不过说来惭愧,以前都是用C ...

  9. C++ string类的实现

    c++中string类的实现 今天面试被考到了, 全给忘记了!!!   //string类的实现 #include <iostream> #include <string.h> ...

随机推荐

  1. Nand Flash与Nor Flash的区别

    区别:http://zhidao.baidu.com/question/1068445.html?qbl=relate_question_0&word=Serial%20Flash%20%D3 ...

  2. 搭建企业cacti服务器

    搭建企业cacti服务器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 今天搭建了cacti,为了方便监控我的交换机~因为查了很多zabbix的资料关于监控交换机的教程~我都屡屡失 ...

  3. 源码安装nginx以及平滑升级

                                                           源码安装nginx以及平滑升级                               ...

  4. hdu5354 Bipartite Graph

    分治+并查集.假设要求[L,mid]的答案,那么很明显,如果一条边的两个端点都>mid的话或者一个端点>mid一个端点<L,说明询问[L,mid]这个区间中任何一点时候,这一条边都是 ...

  5. FM000

    SQL> select To_char(1,'000') from dual; TO_C----001 注意最左边有一个空格 SQL> select To_char(1,'FM000') ...

  6. 解决xfce4桌面图标消失的问题

    问题表现:panel还在,桌面的背景变成灰色,桌面图标消失,桌面右键没反映 解决方法:从登录管理器中登录另一个用户,发现桌面正常,猜测是由于家目录下的配置文件引起的. 删除 ~/.cache/sess ...

  7. JetBrains WebStorm 8 注册码

    UserName:William===== LICENSE BEGIN =====45550-1204201000001SzFN0n1bPII7FnAxnt0DDOPJAINauvJkeVJBuE5b ...

  8. ionic之AngularJS扩展 移动开发(视图导航一)

    目录: 内联模板 : script 路由机制 : 状态机 导航视图 : ion-nav-view 模板视图 : ion-view 导航栏 : ion-nav-bar 回退按钮 : ion-nav-ba ...

  9. 转:Eclipse常用开发插件

    以下是我整理的自己开发过程中的常用Eclipse插件,按字母排序: (1)    AmaterasUML         介绍:Eclipse的UML插件,支持UML活动图,class图,sequen ...

  10. jquery ui和jquery easy ui的区别

    jquery ui 是jquery开发团队 开发,适用于网站式的页面.jquery easyui 是第三方基于jquery开发,适用于应用程序式的页面. 两者的方法调用也略有不同:jquery ui ...