IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 内存泄漏 -> 正文阅读

[C++知识库]C++ 内存泄漏

参考链接
里面的示例代码

typedef struct DATA_{
    DATA_(int size = 10){        
        pVoid = new char[nSize];
        this->size = size;    
    }
    virtual ~DATA_()    {
        if (pVoid){
            delete pVoid;        
        }    
    }
    int nSize;
    void *pVoid;
}DATA, *LPDATA;
struct STRUCT1{
    STRUCT1(int count){        
        pVoid = new DATA[count];
        this->count = count;
    }
    virtual ~STRUCT1(){
        if (pVoid){
            delete pVoid;        
        }    
    }
    int count;
    union    {
        void *pVoid;        
        LPDATA pData;    
    }
}
int main(int argc, char* argv[]){
    for( int i = 0; i < 1000; i++){
        void *p = new STRUCT1( 10 );
        delete p;    
    }
    return 0;
}

造成内存泄漏的原因
在上面这段代码中,STRUCT1中包含了若干个DATA结构,DATA结构又申请了默认为10byte大小的内存,并且内存在对象析构的时候会用delete回收。乍一看这个代码貌似不会泄露内存,其实不然,待我分析:

在C++中构造函数与析构函数的调用是由编译器完成的,其中构造函数的调用一般是在对象空间开辟完以后(栈对象或者堆对象都是一样的),将参数压栈,this指针(对象的起始地址)放入eax寄存器(不同的编译器做法可能不同),然后跳到构造函数去执行。而析构函数的调用则是当对象内存被回收的时候被调用(栈对象是当代码执行到变量可见域外之前调用, 堆对象是在delete语句的位置进行调用)。

然而编译器并是那么智能的可以理解coder的意图,析构函数的调用是根据当前delete的指针类型来确定的,而(下面)这段代码却没有提供类型, 这导致了DATA_的析构函数将不会被调用,内存泄漏就在所难免了。

避免出现内存泄漏的注意事项:

  1. 始终结合使用 memset 和 malloc分配内存,或始终使用 calloc。

  2. 每当向指针写入值时,都要确保对可用字节数和所写入的字节数进行交叉核对。

  3. 在对指针赋值前,要确保没有内存位置会变为孤立的。

  4. 每当释放结构化的元素(而该元素又包含指向动态分配的内存位置的指针)时,都应首先遍历子内存位置并从那里开始释放,然后再遍历回父节点。

  5. 始终正确处理返回动态分配的内存引用的函数返回值。

  6. 每个 malloc 都要有一个对应的 free。

  7. 确保您不是在访问空指针。
    那么存在空指针会出现内存泄漏吗,是不会的,因为空指针本身就没有给他分配内存空间,充其量只是在栈上占用了四个字节的变量空间,一旦脱离域之后自然消失了。
    像如下面这个例子


#include<bits/stdc++.h>
using namespace std;
struct A{
    int b;
    A(){
        cout<<"rrrrrrrrrr"<<endl;
    }
    ~A(){
        cout<<"dddd"<<endl;
    }
};
struct B{
    A* p;
    ~B(){
        cout<<"ooooooooo"<<endl;
        delete p;
        cout<<"mmmmmmmmm"<<endl;
    }
};

int main(){
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    B *e;
    delete e;
    return 0;
}

A里面的b都没有初始化,压根就是个空指针,delete空指针不会产生任何操作,而且空指针本身也不会申请得到空间,但是会出错。
运行结果如下:
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 18:17:37  更:2022-04-22 18:21:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 21:55:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码