new/delete, malloc/free 内存泄漏如何检测

本文介绍了C++中new/delete与malloc/free的区别,包括前者是运算符、可初始化且开辟失败抛异常,后者是库函数、按字节分配内存等。还列举了几种类型的new,最后阐述了检测内存泄漏的方法,如重写函数、用工具库等。

区别:

  1. 首先new/delete是运算符,malloc/free是库函数。
  2. malloc/free只开辟内存不初始化;new/delete及开辟内存也初始化。
  3. 抛出异常的方式:new/delete开辟失败使用抛出bad_alloc;malloc/free通过返回值判断。
  4. malloc和new区别:malloc是c语言中一个库幻术函数,按字节为数据分配内存,返回类型是    ‘ void * ’。因为他不知道分配的内存会被用于什么类型的对象。 new是运算符,需要传入类型,new相当于运算符的重载函数 operator new ->返回值自动转成指定的类指针 int*
  5. free不管是释放单个内存还是数组内存都是函数的调用,传入内存的首地址即可,而delete在删除数组时需要加一个[].

有几种类型的new:

  •         int *p1 = new int (20) ;
  •         int *p2 = new (nothrow) int ;
  •         const int *p3 = new const int(40);
  •         int data = 0; int *p4 = new (&data) int (50);  指定内存地址

C++中,如何设计一个程序检测内存泄漏问题?

  • 内存泄漏就是new操作没有对应的delete,我们可以在全局重写上面这些函数,在new操作里面用映射表记录都有哪些内存被开辟过,delete的时候把相应的内存资源删除掉,new和delete都有对应关系
    #include <iostream>
    #include <unordered_map>
    #include <mutex>
    
    std::unordered_map<void*, std::size_t> allocationMap;
    std::mutex allocMutex;
    
    void* operator new(std::size_t size) {
        std::lock_guard<std::mutex> lock(allocMutex);
        void* ptr = std::malloc(size);
        if (ptr == nullptr) {
            throw std::bad_alloc();
        }
        allocationMap[ptr] = size;
        return ptr;
    }
    
    void operator delete(void* ptr) noexcept {
        std::lock_guard<std::mutex> lock(allocMutex);
        auto it = allocationMap.find(ptr);
        if (it != allocationMap.end()) {
            allocationMap.erase(it);
        }
        std::free(ptr);
    }
    
  • 如果整个系统运行完了,我们发现,映射表记录的一些内存还没有被释放,就存在内存泄漏了!
    void checkForMemoryLeaks() {
        std::lock_guard<std::mutex> lock(allocMutex);
        if (!allocationMap.empty()) {
            std::cout << "Memory leaks detected:\n";
            for (auto& pair : allocationMap) {
                std::cout << "Address: " << pair.first << ", Size: " << pair.second << " bytes\n";
            }
        } else {
            std::cout << "No memory leaks detected.\n";
        }
    }
    

  • 我们用我们自定义的new和delete重载函数 接管整个应用的所有内存管理 ,对内存的开辟和释放都记录;也可以通过编译器既定的宏和API接口,把函数调用堆栈打印出来,到底在哪个源代码的哪一页的哪一行做了new操作没有delete
  • 除了重载 newdelete,还有一些现成的工具和库,如 Valgrind、AddressSanitizer 等,这些工具可以自动检测内存泄漏,而无需修改源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值