有关资源泄漏的一些知识

​​​​​​内存泄漏

1.具体解释

1.1定义 :动态分配的内存(如通过 newmalloc)未被正确释放,导致程序运行期间内存占用持续增长,最终可能耗尽系统资源。

1.2常见场景

1.2.1异常抛出导致 delete 未执行:

cpp 复制代码
void foo() {
    int* p = new int(42);
    throw std::runtime_error("Error"); // 异常抛出,p 未释放
    delete p; // 不会执行
}

1.2.2循环中分配内存但未释放:

cpp 复制代码
while (true) {
    int* p = new int[1000]; // 每次循环分配,但未释放
}

1.2.3对象析构时未释放成员指针:

cpp 复制代码
class BadExample {
    int* data;
public:
    BadExample() : data(new int[100]) {}
    ~BadExample() { /* 忘记 delete[] data; */ } // 泄漏
};

1.2影响:程序性能下降、崩溃(OOM),长期运行的服务可能因内存耗尽被系统终止

1.3防范

1.3.1使用智能指针(std::unique_ptrstd::shared_ptr)自动管理内存

1.3.2遵循RAII(资源获取即初始化) 原则,将资源绑定到对象生命周期

文件描述符泄漏

1.具体解释

2.1定义:打开的文件或套接字未被关闭,导致系统文件描述符耗尽(Linux 默认限制通常为 1024~65536)

2.2常见场景

2.2.1未调用 close()fclose()

cpp 复制代码
void readFile() {
    FILE* f = fopen("data.txt", "r");
    if (f) {
        // 处理文件...
        // 忘记 fclose(f); // 泄漏
    }
}

2.2.2异常路径未关闭文件:

cpp 复制代码
void processFile() {
    int fd = open("data.txt", O_RDONLY);
    if (fd == -1) return;
    // 处理文件...
    if (error_occurred) throw std::runtime_error("Error"); // fd 未关闭
    close(fd); // 可能跳过
}

2.影响:无法打开新文件或网络连接,系统功能受限。

3.防范

2.3.1使用 RAII 封装文件操作(如 std::ifstreamstd::ofstream

2.3.2自定义文件句柄管理类,析构时自动关闭:

cpp 复制代码
class FileHandle {
    int fd;
public:
    FileHandle(const char* path) : fd(open(path, O_RDONLY)) {}
    ~FileHandle() { if (fd != -1) close(fd); }
};

锁泄漏

1.具体解释

3.1定义:获取的锁(如互斥量 std::mutex)未被释放,导致其他线程永久阻塞。

3.2常见场景

3.2.1未调用 unlock()

cpp 复制代码
std::mutex mtx;
void criticalSection() {
    mtx.lock();
    // 处理共享数据...
    // 忘记 mtx.unlock(); // 泄漏
}

3.2.2异常抛出导致锁未释放:

cpp 复制代码
void riskyOperation() {
    std::lock_guard<std::mutex> lock(mtx); // 正确:RAII 自动释放
    // 若使用手动锁:
    mtx.lock();
    throw std::runtime_error("Error"); // 锁未释放
    mtx.unlock();
}

2.影响:线程死锁,系统响应变慢或崩溃

3.防范

3.3.1优先使用 std::lock_guardstd::unique_lock 自动管理锁生命周期

3.3.2避免在持有锁时调用可能抛异常的函数。

网络资源泄漏

1.具体解释

4.1定义:未正确关闭网络连接(如套接字、数据库连接),导致资源耗尽或连接池枯竭。

4.2常见场景

4.2.1未调用 close()disconnect()

4.2.2数据库连接未归还

2.影响:网络服务不可用,数据库连接数超限。

3.防范

4.3.1使用 RAII 封装网络资源(如 std::unique_ptr 自定义删除器)。

4.3.2连接池实现自动回收机制。

循环引用导致的内存泄漏

1.具体解释

5.1定义:在引用计数智能指针(如 std::shared_ptr)中,两个对象相互引用,导致引用计数永远无法归零

5.2常见场景

cpp 复制代码
struct Node {
    std::shared_ptr<Node> next;
    std::shared_ptr<Node> prev; // 双向循环引用
};
auto a = std::make_shared<Node>();
auto b = std::make_shared<Node>();
a->next = b;
b->prev = a; // 引用计数均为 2,离开作用域后不会释放

2.影响:内存无法回收,即使对象不再使用。

3.防范:使用 std::weak_ptr 打破循环

相关推荐
摸鱼的春哥14 分钟前
春哥的Agent通关秘籍07:5分钟实现文件归类助手【实战】
前端·javascript·后端
念念不忘 必有回响17 分钟前
viepress:vue组件展示和源码功能
前端·javascript·vue.js
C澒22 分钟前
多场景多角色前端架构方案:基于页面协议化与模块标准化的通用能力沉淀
前端·架构·系统架构·前端框架
崔庆才丨静觅24 分钟前
稳定好用的 ADSL 拨号代理,就这家了!
前端
江湖有缘25 分钟前
Docker部署music-tag-web音乐标签编辑器
前端·docker·编辑器
恋猫de小郭2 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅8 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60619 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了9 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅9 小时前
实用免费的 Short URL 短链接 API 对接说明
前端