有关资源泄漏的一些知识

​​​​​​内存泄漏

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

相关推荐
灵感__idea3 小时前
JavaScript高级程序设计(第5版):好的编程就是掌控感
前端·javascript·程序员
烛阴4 小时前
Mix
前端·webgl
代码续发4 小时前
前端组件梳理
前端
试图让你心动5 小时前
原生input添加删除图标类似vue里面移入显示删除[jquery]
前端·vue.js·jquery
陈不知代码5 小时前
uniapp创建vue3+ts+pinia+sass项目
前端·uni-app·sass
小王码农记5 小时前
sass中@mixin与 @include
前端·sass
陈琦鹏5 小时前
轻松管理 WebSocket 连接!easy-websocket-client
前端·vue.js·websocket
hui函数6 小时前
掌握JavaScript函数封装与作用域
前端·javascript
行板Andante6 小时前
前端设计中如何在鼠标悬浮时同步修改块内样式
前端
Carlos_sam7 小时前
Opnelayers:ol-wind之Field 类属性和方法详解
前端·javascript