有关资源泄漏的一些知识

​​​​​​内存泄漏

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 打破循环

相关推荐
m0_738120722 小时前
CTFshow系列——命令执行web53-56
前端·安全·web安全·网络安全·ctfshow
Liu.7744 小时前
uniappx鸿蒙适配
前端
山有木兮木有枝_5 小时前
从代码到创作:探索AI图片生成的神奇世界
前端·coze
言兴6 小时前
秋招面试---性能优化(良子大胃袋)
前端·javascript·面试
WebInfra7 小时前
Rspack 1.5 发布:十大新特性速览
前端·javascript·github
雾恋7 小时前
我用 trae 写了一个菜谱小程序(灶搭子)
前端·javascript·uni-app
烛阴8 小时前
TypeScript 中的 `&` 运算符:从入门、踩坑到最佳实践
前端·javascript·typescript
Java 码农9 小时前
nodejs koa留言板案例开发
前端·javascript·npm·node.js
ZhuAiQuan9 小时前
[electron]开发环境驱动识别失败
前端·javascript·electron
nyf_unknown9 小时前
(vue)将dify和ragflow页面嵌入到vue3项目
前端·javascript·vue.js