• C++析构函数造成Debug Assertion Failed的问题


    昨天写了两个程序,均出现了析构函数造成Debug Assertion Failed的问题,由于是初学c++怎么想也想不通问题出在哪里。今天早上经人指点终于明白问题所在了。下面贴出代码和问题解析:(以下内容摘自本人在csdn论坛求助的帖子)

    第一个问题程序:
    //Teacher_Level.h

    #pragma once
    #include<iostream>
    using namespace std;
    int num=0;
    class Teacher
    {
    public:
    char *title;

    Teacher()
    {
    title=new char[50];
    }

    ~Teacher()
    {
    cout<<"called:"<<++num<<endl;
    if(title!=NULL)
    {
    delete[] title;
    title=NULL;
    }
    }

    };

    class Level
    {
    public:
    char *position;

    Level()
    {
    position=new char[50];
    }

    ~Level()
    {
    if(position!=NULL)
    {
    delete[] position;
    position=NULL;
    }
    }
    };


    class Teacher_Level:public Teacher,public Level
    {
    public:
    void show()
    {
    cout<<"The teacher_level:"<<endl;
    cout<<"Title:";
    puts(title);
    cout<<"Position:";
    puts(position);
    }
    };

    //main.cpp

    #include "Teacher_Level.h"
    #include<iostream>
    using namespace std;

    int main()
    {
    Teacher_Level p;
    p.title="professor";
    p.position="header";
    p.show();

    return 0;
    }

    报错如下:



    第二个问题程序:
    //CShop.h

    #pragma once
    #include<string.h>
    #include<iostream>
    using namespace std;

    class CShop
    {
    public:
    char *product;
    int price;

    CShop();
    CShop(char *CProduct,int CPrice);
    ~CShop();

    friend ostream& operator<<(ostream& os,CShop p)
    {
    cout<<"Product:";
    puts(p.product);
    cout<<"Price:";
    cout<<p.price;

    return os;
    }

    };

    CShop::CShop()
    {
    product=new char[50];
    }

    CShop::CShop(char *CProduct,int CPrice)
    {
    product=new char[50];
    strcpy(product,CProduct);
    price=CPrice;
    }

    CShop::~CShop()
    {
    if(product!=NULL)
    {
    delete[] product;
    product=NULL;
    }
    }


    //main.cpp

    #include "CShop.h"
    #include<iostream>
    using namespace std;

    int main()
    {
    char *product="book";
    int price=120;
    CShop p(product,price);
    cout<<"The information of the shop:"<<endl;
    cout<<p<<endl;

    return 0;
    }

    报错如下:

    正确解答:

    第一个:
    Teacher_Level p;  // 这里调用了构造函数,给title分配了内存
    p.title="professor";  // 这里又直接把title指向了常量区,导致析构函数里面企图delete一个常量区指针
    应该照着第二个程序的思路来给title赋值。

    第二个程序的问题稍微有点复杂。
    friend ostream& operator<<(ostream& os,CShop p)
    这里的p是按值传递的,编译器要调用拷贝构造函数来创建一个新对象。但是你自己没写拷贝构造函数,所以编译器自己生成了一个拷贝构造函数,问题由此产生,因为编译器的拷贝构造函数是所谓“浅拷贝”,简单的复制了product的地址。然后销毁这个新对象的时候就把product的地址delete了。你可能会说,delete之后把product赋值NULL了,但那是针对那个临时对象的,main里面的p的product指针没有变动,还指向最初的new的结果,然后退出main的时候就再次delete,导致出错。
    把这个<<重载函数的参数改成&p可以绕过这个问题,但是根本的解决方法是自己写一个拷贝构造函数,不是简单的复制指针,而是重新new一个指针然后strcpy。

    对于这两个程序的问题,我收获很大,特别是第二个让我理解了拷贝构造函数的调用机制。

  • 相关阅读:
    安装xshell6
    eclipse的安装和汉化
    collectd+infludb+grafana实现tomcat JVM监控
    百度网站统计和CNZZ网站统计对比
    shell,计算指定行的和,计算指定列的和
    我为什么要写博客
    kafka监控之topic的lag情况监控
    用rundeck启动tomcat报错
    xwiki升级8.8.4
    矩阵掩膜操作
  • 原文地址:https://www.cnblogs.com/tankeee/p/3957308.html
Copyright © 2020-2023  润新知