c++内存泄露内存溢出和野指针

22 篇文章 1 订阅

一. 内存泄漏
  • 内存泄漏一般是指堆内存的泄漏,也就是程序在运行过程中动态申请的内存空间不再使用后没有及时释放,导致那块内存不能被再次使用。
  • 更广义的内存泄漏还包括未对系统资源的及时释放,比如句柄、socket等没有使用相应的函数释放掉,导致系统资源的浪费。
  • 堆内存的泄漏:
  • 由程序申请的一块内存,且没有任何一个指针指向它,则会发生内存泄露。
  • new或者malloc等动态申请空间之后没有手动delete或者free掉,导致一直占据着内存单元,不能被任何程序再次使用,直到程序结束。
  • 悬空指针:当所指向的对象被释放或者收回,但是没有让指针指向NULL;
#include <iostream>
#include <malloc.h>
using namespace std;

//
void func() {
    int *ptr = (int *)malloc(100000* sizeof(int));
}

void func1() {
    int *pInt = new int[10000];
}

int main() {
    for(int i = 0; i < 10; i++) {
        func();
        func1();
    }
    return 0;
}
  • func()函数和func1()函数都创建了一个局部指针变量,函数调用结束后,指针变量消失,但堆中内存仍然被占用,没有被释放,导致内存泄漏。
  • 使用完这个变量之后却没有及时回收这部分内存,这时我们就说发生了内存泄露。如果发生了内存泄露又没有及时发现,随着程序运行时间的增加,程序越来越大,直到消耗完系统的所有内存,然后系统崩溃。
  • 内存泄漏可分为4类:
  • ①:常发性内存泄漏: 引起内存泄漏的代码会被很多次执行,每次执行的时候都会导致内存泄漏;
  • ②:偶发性内存泄漏:在某些特定的环境下执行引起内存泄漏的代码,才会引起内存泄漏;
  • ③:一次性内存泄漏:代码只会执行一次,但总有一块内存发生泄漏,多见于构造类的时候,析构函数没有释放内存;
  • ④:隐式泄漏:程序运行过程中不断的分配内存,直到结束时才释放内存,但一般服务器程序会运行较长的时间,不及时释放也会导致内存耗尽以至于内存泄漏。
二. 内存溢出
  • 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;
  • 比如申请了一个 int,但给它存了 long 才能存下的数,那就是内存溢出。
  • 内存泄露最终导致内存溢出。
三. 野指针
  • “野指针指未初始化或未清零的指针,它指向的内存地址不是程序员想要的。野指针的成因主要有两种:
  • ①:指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。
  • ②:指针ptrfree或者delete之后,没有置为NULL,让人误以为ptr是个合法的指针。freedelete只是把指针所指的内存给释放掉,但并没有把指针本身释放掉。即,此时,ptr不是NULL指针,但是它也不指向合法的内存块。
  • ③:指针操作超越了变量的作用范围。比如数组越界操作。
#include <iostream>
#include <malloc.h>
using namespace std;

int main() {
    int *p;
    cout << (p == NULL? "p is null": "p is not null") << endl;
    p = nullptr;
    int *ptr = (int *)malloc(30* sizeof(int));
    for(int i = 0; i < 30; i++) {
        *(ptr+i) = 123;
    }
    for(int i = 0; i < 30; i++) {
        cout << *(ptr+i) << "  ";
    }
    cout << endl;
    free(ptr);
    cout << (ptr == NULL? "ptr is null": "ptr is not null") << endl;
    for(int i = 0; i < 10; i++) {
        cout << *(ptr+i) << "  ";
    }
    cout << endl;
    ptr = NULL;
    return 0;
}
//输出
p is not null
123  123  123  123  123  123  123  123  123  123  
123  123  123  123  123  123  123  123  123  123  
123  123  123  123  123  123  123  123  123  123
ptr is not null
6972080  0  7087328  0  123  123  123  123  123  123
  • 任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的;
  • free(ptr)释放的是指针指向的内存!注意!释放的是内存,不是指针!所以还要ptr = NULL
  • 在使用指针的时候还要注意的问题:
  • ①:不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放;
  • ②:在使用指针进行内存操作前记得要先给指针分配一个动态内存。

文章参考1
文章参考2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值