您身边的App定制专业企业--10年开发经验为您护航

18678812288
0531-88887250

C++陷阱之慎用string类

文章编辑:2138com太阳集团 时间:2016年12月20日

大家知道,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;

}


想要了解更多详情欢迎来电咨询18678812288
登陆网址:www.jnydkj.cn。
联系人:王经理。

XML 地图 | Sitemap 地图