zoukankan      html  css  js  c++  java
  • C++陷阱之慎用string类

    我们知道,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;
    }


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

  • 相关阅读:
    urlrewrite地址重写的使用
    算法学习
    数据库之Case When
    速卖通返回503错误
    概述:软件开发工具
    c#将List&lt;T&gt;转换成DataSet
    表单域规范写法
    ant打包和jar包混淆
    Node.js文档和教程
    webpack开发和生产两个环境的配置详解
  • 原文地址:https://www.cnblogs.com/studynote/p/3476993.html
Copyright © 2011-2022 走看看