调程序时忘了为啥,写了一小段测试程序,再简单不过,结果跑出了Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
这个错误信息是在MSVC下的debug模式下跑出的,如果用release版本,则程序直接崩溃!!很严重的错误有木有!
老规矩,先奉上结论:父类没有虚函数(且没有虚析构函数),子类含有虚函数(只含有虚析构函数也算)时,如果指针类型为父类的(但指向子类的实例),就会出现Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)。
我猜测这是由于父类没有虚函数,也就没有为虚函数表分配空间。但是子类有虚函数,也就为虚函数表分配了空间!至于为神马这样就会出错,就不得而知了!
当然,好的编程习惯还是要将父类的析构函数设为虚函数的,这样一来子类的析构函数总是会被调用,这样比较不容易出现内存泄露。
程序如下:
#include <iostream>
class A {
public:
A() {
std::cout << __FUNCTION__ << std::endl;
}
~A() { //解决方案1:将这个函数改为virtual的,推荐~这样释放下面的pB指针时也会调用B的析构函数
std::cout << __FUNCTION__ << std::endl;
}
//virtual void fA(){} //解决方案2:给父类A添加个虚函数
};
class B : public A {
public:
B() {
std::cout << __FUNCTION__ << std::endl;
}
virtual ~B() {//添堵的虚函数1:父类A完全没有虚函数,子类的析构函数设为虚函数照样报错
std::cout << __FUNCTION__ << std::endl;
}
virtual void func() {} //添堵的虚函数2:父类A完全没有虚函数,子类的有虚函数就会报错
};
void main() {
A* pB = new B();
delete pB;
pB = nullptr;;
}
分享到:
相关推荐
Visual C++MFC入门教程 目录 +-- 第一章 VC入门 |------ 1.1 如何学好VC |------ 1.2 理解Windows消息机制 |------ 1.3 利用Visual C++/MFC开发Windows程序的优势 |------ 1.4 利用MFC进行开发的通用方法介绍 |----...
if ((pCurrent->m_nValue) > value) { addBSTreeNode(pCurrent->m_pLeft, value); } else if ((pCurrent->m_nValue) ) { addBSTreeNode(pCurrent->m_pRight, value); } else { //cout重复加入节点"; } } } // 遍历...
例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 2、代码详解 # -*- coding:utf-8 -*- class ListNode: def __init__(self, x): self.val = x self.next = None class Solution: def deleteDuplication(self, ...
phead->next=NULL; } else { rp->next = apcd; rp = apcd; rp->next = NULL; } count ++; printf("successed to create a progress!\n"); AutoSheduling(); } else { printf(...
#include<stdio.h> #include<malloc.h> #include<stdlib.h> #include<string.h> #define NULL 0 /*------------------------------图书信息的结构体------------------------------------*/ struct tushu //图书...
leetcode添加元素使和等于 ...设计LRU缓存结构,该结构在构造时确定大小,假设大小为K,并有如下两个功能 set(key, value):将记录(key, value)插入该结构 get(key):返回key对应的value值 [要求] \1. set和g
简要介绍什么是数据挖掘,详细说明在SQL2005中是如何进行数据挖掘操作的
代码如下: typedef struct node{ struct node *prior; struct node *next; int num;}NODE;/*******双向链表的初始化********/NODE *Init_link(void){ int i; NODE *phead,*pb,*pi;... phead->p
本文实例讲述了C++简单列表类的实现方法。分享给大家供大家参考。具体方法如下: _AFXTLS.CPP文件如下: //#include StdAfx.h #include <stddef> #include <stdio> #include _AFXTLS_.H struct MyThreadData{ ...
面试25题: 题目:合并两个排序的链表 题:输入两个单调递增的链表,输出两个链表... def Merge(self, pHead1, pHead2): # write code here if not pHead1: return pHead2 elif not pHead2: return pHead1 pMerge
(1) 设计一个类 Allocator, 在构造函数中通过传入 (2) 当需要进行内存分配时, 取出 m_pHead 所指 (3) 当需要进行内存释放时, 并不
本文实例为大家分享了C++合并两个排序的链表,供大家参考,具体内容如下 问题描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 struct ListNode { int val; ...
链式栈的进制转换源代码 #define datatype int typedef struct stacknode { int num; datatype data; struct stacknode *pNext; }StackNode;...StackNode * init(StackNode * phead);...#include<stdlib.h>
很实用 描述的MFC的具体实用方法 和有一些实例 对你学习有相当大的帮助
分享给大家供大家参考,具体如下: 问题 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。... $this->val = $x; } }*/ function Merge($pHead1, $pHead2) { if($pHead
获取N号以前的排队人数函数,首先传入参数:链表头指针pHead 然后返回N号以前的排队人数count,如果没有此号或者已经删除了此号,输出error,返回-1。 编写了重置排号机,释放存号的节点,并且不释放头结点pHead 先...
LINKER *FindNode(LINKER *pHead, char *pStr); int ModefyNode(LINKER *pPos); int DeleteNode(LINKER **ppHead, LINKER *pPos); int ClearList(LINKER **ppHead); int ShowList(LINKER *pHead);
运行界面如下: 3.2类、函数及说明 class Inventory { public: Stock *pHead; //定义一个头结点 int count;//定义数量 Inventory();//构造函数 ~Inventory();//析构函数 int Save(char fileName[]);//保存所有项目...
运行界面如下: 3.2类、函数及说明 class Inventory { public: Stock *pHead; //定义一个头结点 int count;//定义数量 Inventory();//构造函数 ~Inventory();//析构函数 int Save(char []);//保存所有项目信息到...
题:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序...