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

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

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

#include <iostream>
#include <string>
#include <stdlib.h> using namespace std; struct flowRecord
{
string app_name;
struct flowRecord *next; }; int main() {
flowRecord *fr = (flowRecord*)malloc(sizeof(flowRecord));
fr->app_name = "hello";
out << fr->app_name << endl;
return ;
}

嗯,当然不是简单的输出 “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*之间的转换,也经常能用到,下面的例子你说输出啥?
#include <iostream>
#include <string> using namespace std; int main() {
string s = "Alexia";
const char *str = s.c_str();
cout << str << endl;
s[] = 'm';
cout << str << endl; return ;
}

嗯,第一个不用多说,第二个输出是“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不是同一种类型

直接看下面的例子:
string s("hello");
cout<<s.size()<<endl; //OK
cout<<"hello".size()<<endl; //ERROR
cout<<s+"world"<<endl; //OK
cout<<"hello"+"world"<<endl; //ERROR

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

C++ string中的几个小陷阱,你掉进过吗?的更多相关文章

  1. java常量池中基本数据类型包装类的小陷阱

    想必大部分学过java的人都应该做过这种题目: public class Test { public static void main(String[] args) { //第一个字符串 String ...

  2. T-SQL中的一些小陷阱

    1,当心ISNULL函数对你的逻辑引起BUG 有人喜欢或者习惯于(并不代表我推荐,甚至这种写法没有任何好处)用ISNULL处理变量这种方式写查询 比如:select * from TestISNULL ...

  3. Unity 3D中C#的性能优化小陷阱

    本篇内容主要来自Unity官方手册: 一般性能优化 一些地方为本人瞎编杜撰,请酌情参考.如有错误,欢迎指出. Unity里C#编程虽然既简单还很爽,但是性能小陷阱还不少.我总强迫自己让代码最优,因此很 ...

  4. ESXi与物理交换机静态链路聚合配置过程中的小陷阱

    作者:陆斌文章来自微信公众号:平台人生 内容简介:ESXi与物理交换机之间配置静态链路聚合时,因为静态链路聚合的特点,在进行down网卡和从虚拟交换机移除网卡的操作时,可能会无法完成故障流量切换,影响 ...

  5. Python中定义函数时参数有默认值的小陷阱

    在定义函数的时候,如果函数的参数有默认值,有两种类型的参数,一种是整数,字符串这种不可变类型,另一种是列表这种可变类型,对于第一种情况没有什么特殊的地方,但是对于可变类型,有一个微妙的小陷阱. 可变类 ...

  6. [C#] string 与 String,大 S 与小 S 之间没有什么不可言说的秘密

    string 与 String,大 S 与小 S 之间没有什么不可言说的秘密 目录 小写 string 与大写 String 声明与初始化 string string 的不可变性 正则 string ...

  7. Java学习过程中的总结的小知识点(长期更新)

    Java学习过程中的总结的小知识点 (主要是自己不会的知识和容易搞错的东西) 计算某个程序运行的时间 long stime=System.currentTimeMillis(); copy3(file ...

  8. 记录Python学习中的几个小问题

    记录Python学习中的几个小问题,和C#\JAVA的习惯都不太一样. 1.Django模板中比较两个值是否相等 错误的做法 <option value="{{group.id}}&q ...

  9. shell中的大括号和小括号

      1.shell中的大括号和小括号   1.${var} 2.$(cmd) 3.() 和 {} 4.${var:-string}, ${var:+string},  ${var:=string}, ...

随机推荐

  1. HTML5表单新属性

    HTML5表单新属性 autofocus  自动聚焦 <input type="text" autofocus> placeholder占位文本 tel         ...

  2. spring启动component-scan类扫描加载,以及@Resource,postConstruct等等注解的解析生效源码

    spring里IOC的原理就不详细写了, 如果想要搞清楚自动扫描组件是如何实现的,还有@Resouce @PostConstruct等注解的工作原理,最好可以先搞清楚整个IOC容器的运作原理再来分析这 ...

  3. java基础知识-二进制

    1.二进制<0B>出现的原因 2. 八进制<0>和十六进制<0X>出现的原因:简化书写和记忆 3.十进制到其他进制的转换方法 method:除以进制数,直到商为0, ...

  4. SRM484

    又Orz了一发rng_58.. 250pt: 题意:给定一种兔子数:当S(x*x) = S(x)*S(x)时,x为兔子数,其中S(x)表示各个数位之和. 思路:本来想了一个复杂度很高的想法..然后想看 ...

  5. Allegro中常见的文件格式

    allegro/APD.jrl : 记录开启 Allegro/APD 期间每一个执行动作的 command .产生在每一次新开启 Allegro/APD 的现行工作目录下 .env : 存在 pcbe ...

  6. 安装sublime3

    Sublime-text-3的安装步骤1添加Sublime-text-3软件包的软件源sudo add-apt-repository ppa:webupd8team/sublime-text-3 2使 ...

  7. Java map的匿名类的初始化

    可以直接使用: Map<String, Object> testMap = new HashMap<String, Object>() { { put("test1& ...

  8. 分形之科赫(Koch)雪花

    科赫曲线是一种分形.其形态似雪花,又称科赫雪花.雪花曲线.瑞典人科赫于1904年提出了著名的“雪花”曲线,这种曲线的作法是,从一个正三角形开始,把每条边分成三等份,然后以各边的中间长度为底边.分别向外 ...

  9. 查看指定spid的脚本当前运行情况和状态

    USE MasterGO declare @spid int; select @spid = 419--null:all ; ;WITH DATA(spid,blockRelationship,blo ...

  10. PKI信息安全知识点

    1. 什么是X.509? X.509标准是ITU-T设计的PKI标准,他是为了解决X.500目录中的身份鉴别和访问控制问题设计的. 2. 数字证书 数字证书的意义在于回答公钥属于谁的问题,以帮助用户安 ...