昨天写了两个程序,均出现了析构函数造成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。

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

C++析构函数造成Debug Assertion Failed的问题的更多相关文章

  1. (转)Debug Assertion Failed! Expression: _pFirstBlock == pHead

      最近在VS上开发C++程序时遇到了这个错误: Debug Assertion Failed! Expression:_pFirstBlock == pHead 如图: 点击Abort之后,查看调用 ...

  2. Qt 调试时的错误——Debug Assertion Failed!

    在VS2008中写qt程序时调试出现此问题,但在release模式下就不存在,在网上搜罗了一圈,是指针的问题. 问题是这样的: 需要打开两个文件,文件中数据类型是float,我使用QVector进行保 ...

  3. Solve Error Debug Assertion Failed Expression vector iterators incompatible Using PCL in Release Mode of VS2010

    When using PCL 1.4.0 in the release mode building under VS2010, we might sometime get the error &quo ...

  4. Debug Assertion Failed!

    问题并没有解决..... 不知道怎么回事,先都没有这样的情况... VC++调程序出现如下错误: Debug   Assertion   Failed!       Program:   D:wyuS ...

  5. C++ error:Debug Assertion Failed.Expression:_BLOCK_TYPE_IS_VALID(phead->nBlock)

    Debug Assertion Failed.Expression:_BLOCK_TYPE_IS_VALID(phead->nBlockUse) 关于上面这个错误,我在上一篇文章中的程序遇到过了 ...

  6. Debug Assertion Failed! Expression: _pFirstBlock == pHead

    点击Abort之后,查看调用栈,发现异常在函数return时被时产生,进一步看是vector的析构函数被调用时产生,以前没开发过C++项目,没什么经验,这个错误让我很困惑,第一,我电脑上并没有f盘:第 ...

  7. opencv检错:程序运行过程正常,当跳出函数时出现断言错误(Debug Assertion Failed)

    转载http://blog.csdn.net/u012327581/article/details/51351780 1.问题描述 在VS2015下配置好Opencv后,程序在函数运行过程中正常,调试 ...

  8. MFC:“Debug Assertion Failed!” ——自动生成的单文档程序项目编译运行就有错误

    今天照着孙鑫老师的VC++教程学习文件的操作,VS2010,单文档应用程序,项目文件命名为File,也就有了自动生成的CFileDoc.CFileView等类,一进去就编译运行(就是最初自动生成的项目 ...

  9. 读书笔记——Windows核心编程(2)禁止C运行时触发的所有Debug Assertion Failed对话框

    1 定义一个函数 void _invalid_parameter( const wchar_t * expression, const wchar_t * function, const wchar_ ...

随机推荐

  1. AR/VR-VR-Info-Micron-Insight:虚拟现实开辟心理健康新途径

    ylbtech-AR/VR-VR-Info-Micron-Insight:虚拟现实开辟心理健康新途径 1.返回顶部 1. 虚拟现实开辟心理健康新途径 全国心理疾病联盟最近发表的一份报告揭示了惊人的统计 ...

  2. 如何更改linux文件的拥有者及用户…

    本文整理自: http://blog.163.com/yanenshun@126/blog/static/128388169201203011157308/ http://ydlmlh.iteye.c ...

  3. 3、scala数组

    一.Array .Array Buffer 1.Array 在Scala中,Array代表的含义与Java中类似,也是长度不可改变的数组. 此外,由于Scala与Java都是运行在JVM中,双方可以互 ...

  4. vmware中centos6.5无法启动拷贝出里面的资料的方法

    先说一下我的环境:windows7-x64位机器下安装的vmware虚拟机,里面安装的是centos6.5-x64位的系统. 系统崩溃的原因:从cenos拖拽一个文件到win7下,结果就卡死了.整个系 ...

  5. Razor的主版页面框架

    类似于2.0版本中的MasterPage主版页面框架,不过mvc3.0推出的RazorView内建的主版页面语法与原本的webFormview的MasterPage相差甚远   1,Razor的页面执 ...

  6. 修改mac host文件绑定域名

    打开终端在终端terminal中输入 sudo vi /etc/hosts 上一步输入完成之后按enter回车键,如果当前用户账号有密码,则在按完之后会提示输入密码,此时输入当前账户密码后继续按ert ...

  7. poj3667(线段树区间合并&区间查询)

    题目链接: http://poj.org/problem?id=3667 题意:第一行输入 n, m表示有 n 间房间(连成一排的), 接下来有 m 行输入, 对于接下来的 m 行输入: 1 x : ...

  8. 洛谷P3646 [APIO2015]巴厘岛的雕塑(数位dp)

    传送门 话说莫非所有位运算都可以用贪心解决么……太珂怕啦…… 一直把或运算看成异或算我傻逼…… 考虑从高位到低位贪心,如果能使答案第$i$位为0那么肯定比不为$0$更优 然后考虑第$i$位是否能为$0 ...

  9. 获取URL地址栏参数(正则表达式)

    ]] = isEncode ? decodeURIComponent(arg[2]) : arg[2]; }); return obj;}

  10. Java无模板导出Excel,Apache-POI插件实现

    开发环境 jdk 1.8 Maven 3.6 Tomcat 8.5 SpringBoot 2.1.4.RELEASE Apache-POI 3.6 Idea 注意: 我是在现有的基于SpringBoo ...