惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
人人都是产品经理
人人都是产品经理
Project Zero
Project Zero
T
Tailwind CSS Blog
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
L
LINUX DO - 热门话题
Spread Privacy
Spread Privacy
大猫的无限游戏
大猫的无限游戏
Google DeepMind News
Google DeepMind News
The Hacker News
The Hacker News
C
Cisco Blogs
T
The Exploit Database - CXSecurity.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
Scott Helme
Scott Helme
Security Archives - TechRepublic
Security Archives - TechRepublic
H
Heimdal Security Blog
博客园 - 【当耐特】
W
WeLiveSecurity
J
Java Code Geeks
Latest news
Latest news
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Troy Hunt's Blog
博客园 - Franky
月光博客
月光博客
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
PCI Perspectives
PCI Perspectives
博客园_首页
C
CERT Recently Published Vulnerability Notes
P
Proofpoint News Feed
P
Palo Alto Networks Blog
I
InfoQ
Security Latest
Security Latest
Hacker News: Ask HN
Hacker News: Ask HN
Microsoft Azure Blog
Microsoft Azure Blog
M
MIT News - Artificial intelligence
Help Net Security
Help Net Security
F
Full Disclosure
Cyberwarzone
Cyberwarzone
D
DataBreaches.Net
The Cloudflare Blog
S
Securelist
美团技术团队
C
Cybersecurity and Infrastructure Security Agency CISA
AI
AI
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events

博客园 - 舒方小院

六一新玩具 some interesting words [原创] 算法题 Zero Sum的一种解法 Linux下压缩不包含路径信息的压缩包 [ZzDW] 关于Java对象序列化您不知道的5件事 [ZzZz && momo] linux 误删 恢复rm -rf [转载] Windows如何在cmd命令行中查看、修改、删除与添加、设置环境变量 [转载] Linux的capability深入分析 [攻略转载] 在飞机上睡觉的七大攻略 [转载] ftp的模式ACTIVE&PASSIVE [转载] QQ黑名单 [转载] Eclipse快捷键 10个最有用的快捷键 [转载] Mysql常用命令行大全 [转载] php java交互 php/java bridge [转载] MySQL命令行下执行.sql脚本详解 [转载] rpm 常用命令 [转载] 控制寄存器(CR0,CR1,CR2,CR3,CR4) [转载] 汇编中AREA和ENTRY理解 [转载] Centos下如何解包rpm文件
生命期是个不可大意的问题
舒方小院 · 2012-04-26 · via 博客园 - 舒方小院

中午同事考了一个问题,其实很简单,但一时间没看出来,仔细回味,发现有点味道。

代码如下 

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

问这样的做法是否有问题?

其实是有问题的,这里涉及到两个关于生命期的问题:

1. string对象的c_str()方法,返回的C型字符串(以\0结尾的字符数组),其生命期是由该对象维护的。 

2.  在第8行的表达式中,string("hello")是一个临时对象,而该临时对象的生命期,在赋值语句执行完后就已经结束了。

因此,在第九行pCArray指向的那块区域,已经是个无效的内存区域,这样的做法是错误的,也是危险的。

基本功就在于对于小概念的牢固掌握啊!

附:C++ 临时对象的生命周期

有关临时对象的生命周期有三种情况:

1)一般情况:临时性对象的被摧毁,应该是对完整表达式(full-expression)求值过程中的最后一个步骤。该完整表达式造成临时对象的产生。
例:

 1 #include <iostream>
 2 using namespace std;
 3 class A
 4 {
 5 public:
 6    A(int i): m_i(i)
 7    {  cout << "A(): " << m_i << endl;
 8    }
 9    ~A()
10    {  cout << "~A(): " << m_i << endl;
11    }
12    A operator+(const A& rhs)
13    {  cout << "A operator+(const A& rhs)" << endl;
14       return A(m_i + rhs.m_i);
15    }
16    int m_i;
17 };
18 int main()
19 {  A a1(1), a2(2);
20    a1 + a2;
21    cout << "------------------------------------" << endl; 
22    //运行到这里,a1 + a2产生的临时变量已经被释放
23    return 0;
24 }

2)凡含有表达式执行结果的临时性对象,应该存留到object的初始化操作完成为止。
例:

 1 #include <iostream>
 2 using namespace std;
 3 class A
 4 {
 5 public:
 6    A(int i = 0): m_i(i)
 7    {  cout << "A(): " << m_i << endl;
 8    }
 9    ~A()
10    {  cout << "~A(): " << m_i << endl;
11    }
12    A operator+(const A& rhs)
13    {  cout << "A operator+(const A& rhs)" << endl;
14       return A(m_i + rhs.m_i);
15    }
16    A& operator=(const A& rhs)
17    {  cout << "A& operator=(const A& rhs)" << endl;
18       m_i += rhs.m_i;
19       return *this;
20    }
21    int m_i;
22 };
23 int main()
24 {  A a1(1), a2(2);
25    A a3;
26    a3 = a1 + a2; 
27    //a1 + a2产生的临时变量在a3的赋值操作完成后,才释放
28    return 0;
29 }

3)如果一个临时性对象被绑定于一个reference,对象将残留,直到被初始化之reference的生命结束,或直到临时对象的生命范畴(scope)结束——视哪一种情况先到达而定。
例:

 1 #include <iostream>
 2 using namespace std;
 3 class A
 4 {  friend ostream& operator<<(ostream& os, const A&);
 5 public:
 6    A()
 7    {
 8    }
 9    A(const A&)
10    {  cout << "A(const A&)" << endl;
11    }
12    ~A()
13    {  cout << "~A()" << endl;
14    }
15 };
16 ostream& operator<<(ostream& os, const A&)
17 {  os << "ostream& operator<<(ostream& os, const A&)" << endl;
18    return os;
19 }
20 const A& f(const A& a)
21 {  return a;
22 }
23 int main(int argc, char* argv[])
24 {
25    {  const A& a = A();
26       cout << "-------------------" << endl;
27    }
28    //直到被初始化之reference的生命结束
29   cout  << f(A()) << endl; 
30    //直到临时对象的生命范畴(scope)结束:
31    //临时对象的const引用在f的参数上(而不是返回值)。
32    //这个引用在f()返回的时候就结束了,但是临时对象未必销毁。
33    cout << "-------------------" << endl;
34   return 0;
35 }