C++请不要问我string s=”a”+”b”分配了几次内存

简介:

C++请不要问我string s=”a”+”b”分配了几次内存

当时技术能力有限,写得很扯蛋,观点完全是错误的,现在的观点是:"a"+"b"会被编译成"ab",这块内存在编译器就分配好了,可能存放在.data段或是.rdata段,s指向这个"ab"的首地址,执行这行代码其实就是在线程栈中加一个指向"ab"首地址的指针。如果产生这个指针算一次内存分配的话,那就是分配了1次内存,否则就是0次。下面的内容就不要看了,以免误导你

       首先我要告诉你,string s="a"+"b";C++中连编译都通过不了,错误提示:“+:不能添加两个指针”。你说他分配几次内存。为什么报错呢,原因很简单,a是一个字符数组,字符数组没有自己的加法运算符。你硬是要这么写,自己实现去,当然在javajsC#(我还是个C#程序员啊,什么时候才能成为C++程序员呢?哥带着这个难题一直在学习C++)中这句话是正确的。那是因为这些语言把一些基础的东西都封装了,或者说这些语言实现了字符数组的加法运算符。

   当我们把这句话改成string a=a;string s=a+b;就没有问题了。现在a是一个字符串,有现成的加法运算符,加法运算符的右边参数应该为字符串,字符数组,字符,指向字符串的指针等,右边参数为intbool型的没有重载。

   那么这两句话到底分配了几次内存呢,有人说2次,有人说3次。我说4次。

   有人说编译器优化,只需要1次,编译器优化我真的管不了。

   2次的人可能认为:“a”一次,b一次,共两次

   3次的人可能认为:“a”一次,b一次,a+b要分配一块新的内存。因为必须重新分配一块内存,来存储ab。如果是a+=b;就不用了,编译器会把a+b的值存在a所在的空间中,如果空间不够,应该会分配一块更大的内存来存储a+b的值(存不下,不给一块更大的空间,行吗?)

   以上三次是必须,第四次分配内存发生在将a+b的值赋给s,即s=ab。我是在反复看Effective C++时不经意间发现的。Effective C++条款15: operator=返回*this的引用,解释得非常清楚。我在这里简要说一下。

       string类的operator=的源码大致如下:

 string& string::operator=(const string& rhs)
 {

   ...

   return *this;    // 返回左边的对象

   }

  因为赋值语句的右边参数不是正确的类型——它是一个字符数组”ab”,不是一个string——编译器就要产生一个临时的string对象使得函数继续运行。就是说,编译器必须产生大致像下面这样的代码:

  const string temp("ab");// 产生临时string,这句话不分配内存才怪,哈哈
  s = temp;           // 临时string传给operator=

 

如果string类的operator=的源码大致如下:(即参数中的const去掉)

  string& string::operator=( string& rhs)

   {

  ...

  return *this;    // 返回当前的对象

    }

  那么string s=a+”b”;编译肯定是通过不了的。因为”b”是个常量字符串,把常量字符串赋给non-const字符串肯定是不行的。

调用string& string::operator=方法时,参数为值传递或者是常量引用传递,都会产生临时变量,并用形参初始化临时变量,当然必须为这个临时变量分配内存,等函数调用完成,系统自动释放临时变量的内存,当然我们也知道这个临时变量的内存不是分配在堆中,而是分配在栈中。

       是的,string s=”a”+”b”;就是分配了4次内存。  

  作者:陈太汉


本文转自啊汉博客园博客,原文链接:http://www.cnblogs.com/hlxs/archive/2011/08/08/2131147.html

目录
相关文章
|
28天前
|
存储 C++ 容器
C++入门指南:string类文档详细解析(非常经典,建议收藏)
C++入门指南:string类文档详细解析(非常经典,建议收藏)
37 0
|
28天前
|
存储 编译器 C语言
C++_String增删查改模拟实现
C++_String增删查改模拟实现
47 0
|
2天前
|
存储 人工智能 程序员
【重学C++】【内存】关于C++内存分区,你可能忽视的那些细节
【重学C++】【内存】关于C++内存分区,你可能忽视的那些细节
28 1
|
6天前
|
存储 安全 C语言
【C++】string类
【C++】string类
|
存储 编译器 Linux
标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”
标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”
|
8天前
|
编译器 C++
标准库中的string类(上)——“C++”
标准库中的string类(上)——“C++”
|
18天前
|
存储 算法 C语言
【C++初阶】8. STL初阶 + String类
【C++初阶】8. STL初阶 + String类
48 1
|
18天前
|
C语言 C++
【C++初阶】9. string类的模拟实现
【C++初阶】9. string类的模拟实现
38 1
|
23天前
|
NoSQL C++
c++中包含string成员的结构体拷贝导致的double free问题
c++中包含string成员的结构体拷贝导致的double free问题
8 0
|
26天前
|
存储 编译器 程序员
【C语言】内存的动态分配与释放
【C语言】内存的动态分配与释放
27 0