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

    ylbtech-IoT:目录 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://ylbtech.c ...

  2. source和sh执行脚本时的差异

    在CentOS7下,有如下脚:sh02.sh. 1 用sh或者bash执行 先执行echo $firstname $lastname 再执行 sh sh02.sh 最后执行 echo $firstna ...

  3. GET和POST的区别及get和post关于请求的编解码的问题

    GET和POST的本质区别是什么?        使用GET,form中的数据将编码到url中,而使用POST的form中的数据则在http协议的header中传输.在使用上,当且仅当请求幂等(字面意 ...

  4. Redux API之combineReducers

    combineReducers(reducers) 随着应用变得复杂,需要对 reducer 函数 进行拆分,拆分后的每一块独立负责管理 state 的一部分. combineReducers 辅助函 ...

  5. Linux&nbsp;rpm&nbsp;命令参数使用…

    RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的"添加/删除程序" rpm 执行安装包 二进制包(Binary)以及源代码 ...

  6. 1.5 webshell文件上传漏洞分析溯源(1~4)

    webshell文件上传漏洞分析溯源(第一题) 我们先来看基础页面: 先上传1.php ---->   ,好吧意料之中 上传1.png  ---->   我们查看页面元素 -----> ...

  7. ACM-ICPC2018北京网络赛 Saving Tang Monk II(bfs+优先队列)

    题目1 : Saving Tang Monk II 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 <Journey to the West>(also < ...

  8. HDU-6395 多校7 Sequence(除法分块+矩阵快速幂)

    Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  9. MATLAB---make与makefile简单介绍

    1 make.makefile概述 makefile定义了一系列的规则,来规定哪些部分先编译,哪些部分后编译,写好makefile以后,只需一个make命令就可以让整个工程完全自动编译,所以简单的说, ...

  10. E20190419-hm

    diagram n. 图表; 示意图; 图解; [数] 线图; contingency n. 意外事故,偶发事件; 可能性,偶然性; [审计] 意外开支; crash v. 碰撞; 使发出巨响; 暴跌 ...