如何将类外堆内存与继承中的动态内存管理描述为一个?
摘要:类外堆内存 基本概念 定义:当类对象的成员变量是指针引用,且指向通过 malloc()、new、new[] 等操作符分配的额外堆内存时,这些内存被称为「类外堆内存」。 核心特点:类外堆内存不会随类对象的生命周期结束而自动释放,必须手动调用
类外堆内存
基本概念
定义:当类对象的成员变量是指针/引用,且指向通过 malloc()、new、new[] 等操作符分配的额外堆内存时,这些内存被称为「类外堆内存」。
核心特点:类外堆内存不会随类对象的生命周期结束而自动释放,必须手动调用 free()、delete、delete[] 等操作释放,否则会导致内存泄漏。
重要性:类外堆内存是 C++ 内存泄漏的主要诱因之一,也是智能指针设计的核心背景。
默认情况下的内存泄漏
当类中分配了类外堆内存,但未在析构函数中释放时,会导致内存泄漏。以下是典型示例及检测结果:
示例代码(内存泄漏)
// memoryLeak.cpp
#include <iostream>
using namespace std;
class A {
char *p; // 指向类外堆内存的指针
public:
A() { p = new char[1000]; } // 分配 1000 字节堆内存
~A() { cout << "析构" << endl; } // 未释放 p 指向的堆内存
};
int main(int argc, char const *argv[]) {
A a; // 局部对象,生命周期结束时自动调用 ~A()
return 0;
}
内存泄漏检测(valgrind 工具)
gec@ubuntu:~$ valgrind ./memoryLeak
==154251== Memcheck, a memory error detector
==154251== Copyright (C) 2002-2017, and GNU GPLd, by Julian Seward et al.
==154251== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==154251== Command: ./memoryLeak
==154251==
析构
==154251==
==154251== HEAP SUMMARY:
==154251== in use at exit: 1,000 bytes in 1 blocks
==154251== total heap usage: 2 allocs, 1 frees, 73,704 bytes allocated
==154251==
==154251== LEAK SUMMARY:
==154251== definitely lost: 1,000 bytes in 1 blocks
==154251== indirectly lost: 0 bytes in 0 blocks
==154251== possibly lost: 0 bytes in 0 blocks
==154251== still reachable: 0 bytes in 0 blocks
==154251== suppressed: 0 bytes in 0 blocks
结论:即使析构函数执行,未释放的类外堆内存仍会泄漏(此处泄漏 1000 字节)。
析构函数正确释放内存
核心原则
只要类中分配了类外堆内存,必须重写析构函数,并在其中按「分配方式匹配释放方式」的规则释放内存。
