C++类中,有时候使用到传值调用(对象实体做参数),遇到这种情况,可要小心了!特别是当你所传值的对象生命周期较长,而非临时对象(生命周期段)的时候。来看看下面的情况:

#include <iostream>
using namespace std;
 
class Text
{
private:
    char * str;
 
public:
    Text(){str = new char[20];::memset(str,0,20);}
    void SetText(char * str)
    {
        strcpy(this->str,str);
    }
    char * GetText() const{return str;}
    ~Text()
    {
        cout << "~Text Destruction" << endl;
        delete [] str;
        cout << "~Text Over" << endl;
    }
};
 
void Print(Text str)
{
    cout << str.GetText() << endl;
}
 
int main()
{
    Text t;
    t.SetText("abc");
    Print(t);
    return 1;
}

上面执行的结果程序崩溃了。原因:

Print(Text str)在对str进行复制构造的时候,没有进行深度拷贝;当 Print退出的时候,因为是临时对象(函数初始时构造),对str进行析构,此时还没有任何破绽;但回到main,继而退出main 的时候,又对t进行析构,但此时t内的str中的内容已经被销毁。由于对一内存空间实施了两次销毁,于是出现内存出错。

解决方法:

    1. 重写浅拷贝。像一下版本,不同的情况要作出适当的调整:

      #include <iostream>
      using namespace std;
       
      class Text
      {
      private:
          char * str;
       
      public:
          Text(){str = new char[20];::memset(str,0,20);}
          Text(Text &t)
          {
              str = new char[20];
              strcpy(str,t.GetText());
          }
          void SetText(char * str)
          {
              strcpy(this->str,str);
          }
          char * GetText() const{return str;}
          ~Text()
          {
              cout << "~Text Destruction" << endl;
              delete [] str;
              cout << "~Text Over" << endl;
          }
      };
       
      void Print(Text str)
      {
          cout << str.GetText() << endl;
      }
       
      int main()
      {
          Text t;
          t.SetText("abc");
          Print(t);
          return 1;
      }
    2. (推荐)不使用传值调用。就像下面书写如下Print版本: 
      void Print(Text &str)
      {
          cout << str.GetText() << endl;
      }
    3. 除非对象内所有的成员读属非指针内存内容,那么谨慎使用文章前面的用法。

小心指针被delete两次的更多相关文章

  1. C++ delete 两次

    转载自:http://blog.csdn.net/jxluofeng/article/details/19766801 <问题>危险的代码: int* p=new int(1);   de ...

  2. 问题:C++ 删除数组指针实用 delete []变量 汇编怎么实现的?

    问题:C++ 删除数组指针实用  delete []变量    汇编怎么实现的?

  3. 迷途指针 new delete

    编程中有一种很难发现的错误是迷途指针.迷途指针也叫悬浮指针.失控指针,是党对一个指针进行delete操作后——这样会释放它所指向的内存——并没有把它设置为空时产生的.而后,如果你没有重新赋值就试图再次 ...

  4. 《挑战30天C++入门极限》c++中指针学习的两个绝好例子

        c/c++中指针学习的两个绝好例子 对于众多人提出的c/c++中指针难学的问题做个总结: 指针学习不好关键是概念不清造成的,说的简单点就是书没有认真看,指针的学习犹如人在学习饶口令不多看多学多 ...

  5. C语言:指针实现交换两个变量的值

    用指针交换两个变量的值(10分) 题目内容: 用指针交换两个变量的值 主函数参考: int main( ) { int a,b; scanf("%d%d",&a,& ...

  6. C语言:通过函数指针来完成两个数的加减乘除(函数指针当做参数使用)

    // //  main.c //  Function_pointer // //  Created by mac on 15/8/2. //  Copyright (c) 2015年. All rig ...

  7. C语言:通过函数指针来完成两个数的加减乘除

    // //  main.c //  Function_pointer // //  Created by mac on 15/8/2. //  Copyright (c) 2015年. All rig ...

  8. C++ 指针 new delete int*与string

    一 指针 string和int 都可以认为是四个字节sizeof(string)==4, string是个类,它的空间在堆动态分配 二.delete 只是释放空间 三.new 数组 int size= ...

  9. mysql delete两种关联删除方式

    基本格式:  DELETE t1 FROM t1,t2 WHERE t1.id=t2.id 或 DELETE FROM t1 USING t1,t2 WHERE t1.id=t2.id  示例应用: ...

随机推荐

  1. 使用 iMacros 来自动化日常的工作

    利用 iMacros 的浏览器附加组件来提高工作效率 介绍 iMacros 这个强大的工具,使用简单的范例演示了如何使用这个工具来完成对于网页的操作,对于大量的具有重复性的工作内容尤其可以提高效率.对 ...

  2. 【LeetCode】3.Longest Substring Without Repeating Characters 最长无重复子串

    题目: Given a string, find the length of the longest substring without repeating characters. Examples: ...

  3. js的replace方法

    今天在项目中发现,js的replace方法,其实只是替换第一个匹配的字符: 比如 backstreetboy.replace('b','B') 得到的结果是Backstreetboy,只是替换了第一个 ...

  4. java.lang.IllegalArgumentException

    org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.Persiste ...

  5. alter table <表名 > add constraint <主键名>用法

    alter table <表名 > add constraint  <主键名>用法介绍 1.主键约束: 要对一个列加主键约束的话,这列就必须要满足的条件就是分空 因为主键约束: ...

  6. C++异常:no matching function for call to "Matrix(Matrix&)"

    C++异常:no matching function for call to "Matrix(Matrix&)" 我定义了一个类叫Matrix,其中构造函数explicit ...

  7. hql语句关联查询(select new )

    在  new bean()中,对象里要有其构造方法,查询参数必须是构造方法中的参数,get set也要同步 类似于 String hql= "select  new A(a.id, a.na ...

  8. 本机不安装Oracle客户端,使用PL/SQL Developer连接远程数据库

    附送PL/SQL Developer11中文版下载地址 1.先到Oracle网站下载Instant Client : http://www.oracle.com/technetwork/databas ...

  9. CSS强制文本在一行内显示若有多余字符则使用省略号表示

    这篇文章主要介绍了强制文本在一行内显示,多余字符使用省略号,设置或检索是否使用一个省略标记(...)标示对象内文本的溢出.对应的脚本特性为textOverflow 设置或检索是否使用一个省略标记(.. ...

  10. 使用SSL确保通信中的数据安全

    #region Server /// <summary> /// 用于保存非对称加密(数字证书)的公钥 /// </summary> private string public ...