首页 > 编程笔记 > C++笔记 阅读:11

内存泄漏是什么,C++内存泄漏详解(附带实例)

堆内存需要由开发者自行申请和回收。C++ 开发者使用 new 关键字申请堆内存时,会用一个指针指向它,且释放堆内存前该指针都不能指向其他位置。一旦指针指向了其他位置,该堆内存将无法再被定位和回收,犹如丢失了一般,这种情况称为内存泄漏。

内存泄漏是指在程序运行过程中,由于某些原因导致某些内存块无法被回收而一直占用系统资源的现象。内存泄露会导致程序运行速度变慢甚至崩溃。注意,内存泄漏主要针对堆内存。

【实例】丢失的内存。这是一个反例,会造成内存出错。具体代码如下:
#include <iostream>
using namespace std;
int main()
{
    float *pF = NULL; // 定义指针 pF
    pF = new float; // 申请一块堆内存,pF 指向它
    *pF = 4.321f; // 将 4.321 存入堆内存空间
    float f2 = 5.321f;
    cout << "pF 指向的地址:" << pF << endl;
    cout << "*pF 的值:" << *pF << endl; // pF 指向另一地址,此时上面申请的内存将不再可用
    pF = &f2;
    cout << "pF 指向了 f2 的地址:" << pF << endl;
    if (*pF > 5)
    {
        cout << "*pF 的值:" << *pF << endl;
    }
    return 0;
}
程序运行结果为:

pF 指向的地址:0xd51510
*pF 的值:4.321
pF 指向了 f2 的地址:0x6ffe04
*pF 的值:5.321

程序中,pF 开始时指向动态分配的堆内存,后来 pF 的指向发生了改变,导致此块内存无法再被定位,因此无法再被回收。

依靠调试程序很难发现内存泄漏问题。所以,开发者在使用动态堆内存时一定要形成良好的编程习惯。

【实例】回收动态内存。展示回收动态内存的一般处理步骤。具体代码如下:
#include <iostream>
using namespace std;

void swap(int *a, int *b) // 定义 swap() 函数,交换两个数值
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main()
{
    int *p1 = new int; // 申请一块堆内存,p1 指向它
    *p1 = 3; // 堆内存中存放 3
    int k = 5;
    swap(p1, &k); // 调用 swap() 函数,交换数值
    std::cout << "**p1:" << *p1 << std::endl; // 使用 std 名称空间
    std::cout << "k:" << k << std::endl;
    delete p1; // 释放并回收堆内存
    p1 = NULL; // 将 p1 置空,防止使用已销毁的内存
    // 该语句和上一条语句不可颠倒,否则将造成内存泄漏
    return 0;
}
程序运行结果为:

**p1:5
k:3

注意,指针是一种灵活、高效的内存访问机制,可以通过地址对变量直接进行操作。注意,指针只能访问内存,不能访问寄存器,因此也不能访问寄存器变量。

相关文章