C++ string中的几个小陷阱,你掉进过吗?

http://blog.csdn.net/lanxuezaipiao/article/details/24885811

C++开发的项目难免会用到STL的string,使用管理都比char数组(指针)方便的多,但在得心应手的使用过程中也要警惕几个小陷阱,避免我们项目出bug却迟迟找不到原因。

1.  结构体中的string赋值问题

直接通过一个例子说明,下面的例子会输出什么:

[cpp] view plaincopy

  1. #include <iostream>
  2. #include <string>
  3. #include <stdlib.h>
  4. using namespace std;  
  5. struct flowRecord            
  6. {  
  7.     string app_name;                                                              
  8. struct flowRecord *next;  
  9. };  
  10. int main() {  
  11.     flowRecord *fr = (flowRecord*)malloc(sizeof(flowRecord));  
  12.     fr->app_name = "hello";  
  13.     cout << fr->app_name << endl;  
  14. return 0;  
  15. }  

嗯,当然不是简单的输出“hello”了,在Linux下用g++编译后运行试试,会出现“Segmentation fault (core dumped)”,why?问题就出在给fr指针分配内存的时候,注意这里用的是C中的malloc而不是new,如果你换成new再运行,就不会报错了,成功的输出“hello”,那为什么malloc就不行呢?这就要看malloc()与new()的区别了,关于两者的区别是程序员面试中屡问不爽的经典面试题,所以相信一般的程序员都知道它们之间有一个非常重要的区别就是:new在分配内存时会调用默认的构造函数,而malloc不会调用。而STL的string在赋值之前需要调用默认的构造函数以初始化string后才能使用,如赋值、打印等操作,如果使用malloc分配内存,就不会调用string默认的构造函数来初始化结构体中的app_name字符串,因此这里给其直接赋值是错误的,应该使用new操作符。这也提示我们用C++开发程序时,就尽量使用C++中的函数,不要C++与C混合编程,导致使用混淆,比如有时候new分配的内存却用free释放。

2. c_str()函数问题

c_str()函数用于string与const char*之间的转换,也经常能用到,下面的例子你说输出啥?

[cpp] view plaincopy

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;  
  4. int main() {  
  5.     string s = "Alexia";  
  6. const char *str = s.c_str();  
  7.     cout << str << endl;  
  8.     s[1] = 'm';  
  9.     cout << str << endl;  
  10. return 0;  
  11. }  

嗯,第一个不用多说,第二个输出是“Alexia”还是“Amexia”呢?答案是后者,咋一看const char*的值应该是个常量啊,怎么还能改变值呢?哈,又是个经典的面试题:const char*, char const*, char* const的区别是什么?老生常谈的问题,const char*与char const*是等价的,指的是指向字符常量的指针,即指针可以改变指向但其指向的内容不可以改变,而char* const相反,指的是常量指针,即指向不可以改变但指针指向的内容可以改变。因此这里的const char*指向的内容本类是不可以改变的,那么这里为什么改变了呢?这跟str这个const char*的生命周期及string类的实现有关,string的c_str()返回的指针是由string管理的,因此它的生命期是string对象的生命期,而string类的实现实际上封装着一个char*的指针,而c_str()直接返回该指针的引用,因此string对象的改变会直接影响已经执行过的c_str()返回的指针引用。

3. 字符串字面值与标准库string不是同一种类型

直接看下面的例子:

[cpp] view plaincopy

  1. string s("hello");  
  2. cout<<s.size()<<endl;        //OK
  3. cout<<"hello".size()<<endl;  //ERROR
  4. cout<<s+"world"<<endl;       //OK
  5. cout<<"hello"+"world"<<endl; //ERROR

可以看出两者是非常不同的,不能混淆使用。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

Java基础-day06-知识点回顾与练习

Java基础-day06-知识点回顾与练习 1.求和案例 ? 实现代码: package StudentJavaSEday06; public class De...

32930
来自专栏前端吧啦吧啦

涨薪必备Javascript,快点放进小口袋!

14720
来自专栏一个会写诗的程序员的博客

Kotlin 语言极简教程 v0.1 (东海陈光剑)Kotlin 语言极简教程

在 Java 里,声明一个 string 类型,赋一个 null 给这个变量。一旦我们要打印这个字符串的时候,会在运行时曝出空指针错误,因为我们在尝试去读一个空...

10540
来自专栏从流域到海域

Python基本数据类型

其实之前有一篇博客:C\C#\Java\Python 基本数据类型比较 https://cloud.tencent.com/developer/article...

25560
来自专栏静晴轩

类数组借用数组方法

于JavaScript如何将对象转化为数组对象,其用法写法已经很常见且完善,比如JQuery中的makeArray函数对此的实现,也是跟大家想的差不多,只是考虑...

37190
来自专栏web前端教室

不学不知道,sort()方法中的坑

今天的前端零基础课,在讲到js中的sort()排序方法的时候,说sort()这个方法在给数字排序的时候,根本不是按数字大小来排序的。 它是把数字都当成字符串来看...

197100
来自专栏伪君子的梦呓

题解~按照特定的格式输出~C++做法

一共三行,第一行:位数 第二行: 用空格分开的每个数字,注意最后一个数字后没有空格 第三行: 按逆序输出这个数

5740
来自专栏前端吧啦吧啦

涨薪必备Javascript,快点放进小口袋!

31870
来自专栏达摩兵的技术空间

js对象属性

相信对于对象属性大家都或多或少的知道一些,那么本文从属性说开去,看看大家对属性的了解是否有遗漏的部分。

33510
来自专栏chenjx85的技术专栏

leetcode-179-Largest Number(理解规则,自定义cmp函数进行排序)

1、这道题给定一个vector,里面存放着int类型的非负整数,要求把这些非负整数拼起来,尽可能拼成一个最大的整数。

20130

扫码关注云+社区

领取腾讯云代金券