C++析构函数调用异常问题研究

2023-10-26

最近又遇到一个奇葩问题,程序在自己的开发机器和某些机器上运行完好,但是在测试人员的几台机器上运行就直接推出了。开始以为是出现了野指针,因为delete野指针时程序会直接退出。代码翻来覆去过来即便确认没有野指针后问题就陷入了死循环。经过多次调试我发现在我的机器上虽然不崩溃,但是delete对象指针的时候不会走对应的析构函数,这问题就奇怪了。后来终于被我找到了原因。原来在头文件中声明成员变量指针时为了尽量少的包含头文件而使用的前向声明,而在实现文件中又没有包含真正声明该类型的头文件。一般情况下这种使用方式编译器会报错,但是当把指针放在容器中时编译器就不能侦测到错误了。说起来问题比较绕下面用代码写了个例子:

 

father.h

#ifndef FATHER_H_
#define FATHER_H_

struct FatherCalss
{
public:
    virtual double Speak() = 0;
    virtual ~FatherCalss();

};

struct SonCalss:public FatherCalss
{
public:

    virtual ~SonCalss();

};

class GrandsonClass:public SonCalss
{
public:
    virtual double Speak();

    virtual ~GrandsonClass();
};

#endif//FATHER_H_

 

 

father.cpp

#include "stdafx.h"
#include "Father.h"
#include <Windows.h>

FatherCalss::~FatherCalss()
{
    MessageBox(NULL, _T("FatherCalss"), _T("~FatherCalss"), MB_OK);
}

SonCalss::~SonCalss()
{
    MessageBox(NULL, _T("SonCalss"), _T("~SonCalss"), MB_OK);
}

GrandsonClass::~GrandsonClass()
{
    MessageBox(NULL, _T("GrandsonClass"), _T("~GrandsonClass"), MB_OK);
}

double GrandsonClass::Speak()
{
    MessageBox(NULL, _T("Speak"), _T("~GrandsonClass"), MB_OK);
    return 0.0;
}

 

 

first.h

#ifndef FIRST_H__
#define FIRST_H__
#include <vector>

struct FatherCalss;

class First
{
public:
    void CreateObject();
    ~First();

    std::vector<FatherCalss*>     m_VecpFather;
};

#endif // First_h__

 

 

first.cpp

#include "First.h"
#include "Father.h"

void First::CreateObject()
{
    FatherCalss* pFth = new GrandsonClass;
    pFth->Speak();
    m_VecpFather.push_back(new GrandsonClass);
}

First::~First()
{
    for(std::vector<FatherCalss*>::iterator it = m_VecpFather.begin(); it != m_VecpFather.end(); ++it)
    {
        delete *it;
    }
}

 

 

调用代码:

First* pFirst = new First;

pFirst->CreateObject();

for(std::vector<FatherCalss*>::iterator it= pFirst->m_VecpFather.begin(); it != pFirst->m_VecpFather.end(); ++it)
{
    delete *it;
}
pFirst->m_VecpFather.clear();

delete pFirst;

 

 

如上如果 m_VecpFather 不是容器而是 FatherCalss* 则编译器会报错。

运行程序后会发现对象的析构函数根本就没有被执行,这样的行为存在一定的不确定性,程序如果不报错的换实际上会产生内存泄漏。

转载于:https://www.cnblogs.com/xueye9/p/4277593.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++析构函数调用异常问题研究 的相关文章

  • C++_生成随机字符串

    include
  • 每天都在谈SOA和微服务,但你真的理解什么是服务吗?

    近几年来 我一直从事着和面向服务相关的底层软件研发工作 逐渐的形成了一些自己的看法 其中我觉得比较重要的看法就是服务需要一个更准确细致的定义 简单来说 服务的本质就是行为 业务活动 的抽象 为了更好的阐述新服务的概念 并方便与传统的SOA中
  • C/C++语言实现WiFi(socket)数据收发(客户端和服务端)

    目录 客户端 client 服务端 server C C 实现TCP通信 接收WIFI数据 编程环境 VC 6 0 手机端 使用WiFi调试助手 提示 整个过程在局域网中进行 很多编程语言都可以实现socket通信 本博客将通过C C 实现
  • C++中的namespace

    namespace中文意思是命名空间或者叫名字空间 传统的C 只有一个全局的namespace 但是由于现在的程序的规模越来越大 程序的分工越来越细 全局作用域变得越来越拥挤 每个人都可能使用相同的名字来实现不同的库 于是程序员在合并程序的
  • 五. python面向对象(多态 和metaclass=abc.ABCMeta)

    一 多态 多肽 一种事物的多种形态 叫多肽 例如 动物 animal 猫 狗 animal py 文件 动物类 都有名字这个属性 和吃这个方法 class Animal object def init self name self name
  • C语言pcre库的使用及验证IP地址的合法性

    PCRE是一个用C语言编写的正则表达式函数库 它十分易用 同时功能也很强大 性能超过了POSIX正则表达式库和一些经典的正则表达式库 在使用PCRE库时 首先肯定是需要安装pcre的 不过一般的系统都会有自带的PCRE库 不过如果想使用最新
  • 写时拷贝技术(copy-on-write)

    传统的fork 系统调用直接把所有的资源复制给新创建的进程 这种实现过于简单并且效率低下 因为它拷贝的数据也许并不共享 更糟的情况是 如果新进程打算立即执行一个新的映像 那么所有的拷贝都将前功尽弃 Linux的fork 使用写时拷贝 cop
  • BP学习算法-构建三层神经网络

    引 人工神经网络 Artificial Neural Networks 简写为ANNs 也简称为神经网络 NNs 或称作连接模型 Connection Model 是一种模仿动物神经网络行为特征 进行分布式并行信息处理的算法数学模型 这种网
  • ATL字符串转换宏

    有比MultiByteToWideChar和WideCharToMultiByte更简单的字符串转换宏 你相信吗 头文件 d program files microsoft visual studio 8 vc atlmfc include
  • 为何在新建STM工程中全局声明两个宏

    在uVision中新建STM32工程后 需要从STM32标准库中拷贝标准外设驱动到自己的工程目录中 此时需要在工程设置 gt C C 选项卡下的Define文本框中键入这两个全局宏定义 STM32F40 41xxx USE STDPERIP
  • floor(),ceil()函数

    地板 天花板函数 均包含在math h中 意思分别为 返回不大于形参的最小整数和不小于形参的最大整数 include
  • 手把手教你如何写一个三子棋/N子棋的小游戏

    这里写目录标题 第一步 游戏进入界面 第二步 初始化棋盘 第三步 打印棋盘 第四步 玩家和电脑下棋 第五步 判断输赢 三子棋或者N子棋怎么写 让我们先来玩一把 再来看看怎么写 程序运行界面 1为玩游戏 2为清屏 0为退出游戏 我们选1 然后
  • 在聚会中常玩数七的游戏,七的倍数和带有七的数字都不能说,比如14,27,28。请找出1~100的不能说的数字。...

    利用ES5的filter高阶函数来实现 var arr 1 2 3 4 5 6 7 17 27 21 22 28 100 r arr filter function x return x 10 7 x 7 0 alert r 7 14 17
  • 【C/C++】 - Linux下查找函数头文件 以及 man命令拓展

    背景 比如现在需要找C语言 sleep函数的头文件 使用man来查找 可以先man sleep 可以发现出来的默认是sleep 1 是一个User Commands 明显不是我们需要的 这里提示了 看sleep 3 那我们查看下sleep
  • 一个简单的参数帮助框架,c实现

    文章目录 具体实现如下 include
  • 虚函数不能声明为static

    虚函数申明为static报错 class Foo public Foo default static virtual Foo int main Foo foo return 0 main cpp 10 25 error member Foo
  • enable_shared_from_this使用介绍

    文章目录 enable shared from this定义 使用场合 源码实现 注意 enable shared from this定义 定义于头文件 template lt class T gt class enable shared
  • C/C++编程中的算法实现技巧与案例分析

    C C 编程语言因其高效 灵活和底层的特性 被广大开发者用于实现各种复杂算法 本文将通过10个具体的算法案例 详细探讨C C 在算法实现中的技巧和应用 一 冒泡排序 Bubble Sort 冒泡排序 Bubble Sort 是一种简单的排序
  • C++ 字符串比较------strcmp函数和strncmp函数

    strcmp 函数原型 int strcmp const char str1 const char str2 功能 strcmp函数会按照字典顺序逐个比较两个字符串的字符 直到遇到不同的字符或者遇到字符串结束符 0 返回值 该函数返回值如下
  • C++ 中 const 和 constexpr 关键字解析:常量、函数和指针

    很多 C 的初学者看到 const 这个关键字的第一反应都是一头雾水 主要是因为 const 可 以出现在很多的位置 以及后面加入的 constexpr 更是常常感到困惑 今天就为大家一一解释出现它们的含义和以及作用 const 关键字 c

随机推荐

  • Adobe MAX 2020:最新版Photoshop提供AI智能神经滤镜及天空替换等功能

    数据猿年度重磅活动预告 2020年度金猿策划活动 金猿榜单发布 金猿奖杯颁发 即将推出 尽情咨询期待 大数据产业创新服务媒体 聚焦数据 改变商业 数据报道 受新冠疫情影响 今年的Adobe MAX 2020 于北京时间10月21日改为了线上
  • 一个优秀的程序员真的能顶10个普通的程序员吗?

    一个优秀的程序员真的能顶10个普通的程序员吗 一 前言 优秀的程序员 比糟糕的程序员的工作产出高100倍 二 糟糕程序员会有哪些表现 1 无法对代码进行推理 2 没有补救措施 3 代码难以改动 三 优秀程序员是怎么做的呢 1 先进行实验是他
  • Java+SSM+Vue 毕业设计 游戏攻略资讯补丁售卖商城(含源码+论文)

    文章目录 1 项目简介 2 实现效果 2 1 界面展示 3 设计方案 3 1 概述 3 2 系统流程 3 3 系统结构设计 4 项目获取 1 项目简介 Hi 各位同学好呀 这里是M学姐 今天向大家分享一个今年 2022 最新完成的毕业设计项
  • Win32学习笔记(16)消息类型

    1 消息的产生与处理流程 如上图 我们在创建窗口程序中详细介绍了这张图 比如 我们点击某个窗口的时候就会产生消息 操作系统会先判断这个消息是点在了哪个窗口 找到窗口后 会根据窗口对象中的一个成员找到窗口是属于哪个线程的 找到后就会把他封装好
  • 从零开始搭建一个 React 项目 -- 配置篇(一)

    从零开始搭建一个 React 项目 配置篇 一 参考资源 从零搭建完整的React项目模板 Webpack React hooks Mobx Antd 1 项目初始化及常用以来安装配置 1 创建名为 react admin demo 的目录
  • python虚拟环境配置、Python代码打包成exe可执行文件

    背景 因工作需要 要打包一些脚本使其成为exe文件 方便未安装python环境的电脑运行脚本 但是直接使用默认环境的话 会有很多的包 但是其实这个脚本根本用不到 导致生成的exe文件很大或者直接打包失败 所以创建一个虚拟环境 只安装该代码需
  • socket套接字,粘包问题

    目录 scoket套接字 socket工作流程 TCP服务端 TCP客户端 基于TCP 的SOCKET服务端与客户端 基础版本 客户端 加入连接循环 加入通信循环 支持并发的TCP服务端 常见问题 半连接池 粘包问题 TCP协议的特点 解决
  • OpenAI开源!!Whisper语音识别实战!!【环境配置+代码实现】

    目录 环境配置 代码实现 实现 mp4转换为 wav文件 识别后进行关键词匹配并输出关键词出现的次数 完整代码实现请私信 环境配置 安装 ffmpeg 打开网址 https github com BtbN FFmpeg Builds rel
  • vue使用svg自定义icon图标

    1 安装 svg sprite loader svg sprite loader 是用于创建SVG精灵图的Webpack加载程序 通过该插件可以将导入的SVG文件自动生成为symbol标签并插入进html中 安装语句如下 npm insta
  • 关于Spark报错不能连接到Server的解决办法(Failed to connect to master master_hostname:7077)

    问题产生 Spark集群 即可以基于Mesos或YARN来部署 也可以用自带的集群管理器 部署于standalone模式下 笔者在部署standalone模式时 首先 通过如下命令 启动了Master sbin start master s
  • 为什么会有ETH和ETC?the DAO攻击事件2周年祭

    前两天 跟一位HiBlock区块链社区的用户私聊 他问我一个问题 同样是智能合约 为什么会有以太坊和以太经典 又为什么会有相应的ETH和ETC 两者价格还相差如此之大 转给他一篇the DAO事件的文章后突然发现 the DAO攻击事件已经
  • Spring AOP 应用场景之--日志收集(含代码)

    在学习了 Spring AOP 知识之后 只了解了其一些基本的概念 比如它是为了解决 OOP 的弊端 使代码更易于维护 使用了动态代理 Spring 中有两种动态代理实现方式 一种是 JDK 一种是Cglib 使用场景有权限 缓存 日志 b
  • linux命令大全 which

    参考 Linux命令大全 程序员工具箱 1 命令 which 从 PATH 路径下查找某个命令的全路径 2 使用样例 查看 java 命令的全路径 which java 3 使用方法 which programnam
  • 基于JdbcTemplate的一种通用数据库操作帮助工具

    工具介绍 基于JdbcTemplate的通用操作数据库的帮助工具 借助阿里巴巴的开源工具fastjson实现实体的转json字符串以及params的解析 用法 1 建立与数据库表相对应的entity对象 package cn flyzy20
  • APB协议UVM验证环境的搭建

    APB协议UVM验证环境的搭建 一 编译文件 只需编译这两个文件即可 apb pkg sv 里面包含了 apb svh 即编译apb pkg sv这个文件的同时 也会编译所需要的所有的头文件 ifndef APB PKG SV define
  • 绕过专题

    绕过验证码专题 原理 直接截取返回包的cookie或者json流中的验证码进行绕过 提取出验证码进行直接验证即可 gt 绕过 方法 利用burp中的Extractor或者是Bp自带的Marco进行自动化测试 典型类型 如返回包的cookie
  • Java生成一个包含所有数字大小写字母的集合

    利用循环给集合添加所有数字和字母 import java util ArrayList ArrayList
  • steam移动所有文件至新库文件夹失败_不想次次重复下载游戏?手把手教你打造移动游戏、软件库...

    大家好 我是黄昏百分百 之前我有幸获邀参与了七彩虹RTX 3080显卡的媒体首测 在测试过程中 我购买了很多的3A大作 下着下着游戏 就发现固态硬盘不够用了 所以 我觉得升级我的固态硬盘 于是 就有了今天这篇如何通过固态硬盘打造移动游戏 软
  • 【Android自动化测试】5个必备的测试框架

    Appium Appium是一个开源的移动测试工具 支持iOS和Android 它可以用来测试任何类型的移动应用 原生 网络和混合 作为一个跨平台的工具 你可以在不同的平台上运行相同的测试 为了实现跨平台的功能 Appium使用了供应商提供
  • C++析构函数调用异常问题研究

    最近又遇到一个奇葩问题 程序在自己的开发机器和某些机器上运行完好 但是在测试人员的几台机器上运行就直接推出了 开始以为是出现了野指针 因为delete野指针时程序会直接退出 代码翻来覆去过来即便确认没有野指针后问题就陷入了死循环 经过多次调