佛山网站建设公司大全,网速,银川建立网站,公司装修材料会计分录在 C 的内存管理中内存泄漏#xff08;memory leak#xff09;通常是指程序在分配内存后#xff0c;由于未能正确释放#xff08;如忘记调用 free 或 delete#xff09;#xff0c;导致这部分内存无法被再次使用。
一、内存分配方式
通常内存分配有以下三种#xff1a…在 C 的内存管理中内存泄漏memory leak通常是指程序在分配内存后由于未能正确释放如忘记调用 free 或 delete导致这部分内存无法被再次使用。
一、内存分配方式
通常内存分配有以下三种
从静态存储区域分配内存在程序编译的时候就已经分配好这块内存在程序的整个运行期间都存在。例如全局变量、static变量。在栈上创建在执行函数时。函数中的局部变量的存储单元都可以在栈上创建函数执行结束后这些存储单元会被自动释放。栈内存分配运算内置于处理器的指令集中效率很高但是可分配的内存容量有限。从堆上分配亦称动态内存分配。在执行函数期间可以通过malloc或者new申请所需大小的内存单元程序员自己负责何时用free或者delete释放掉申请的内存单元。 动态内存的生存周期由程序员决定使用非常灵活。但是如果在堆上分配的空间就有责任回收它否则运行的程序会出现内存泄漏。此外频繁的分配和释放不同大小的堆空间将会产生堆内碎块。
二、程序内存空间
一个程序将操作系统分配给其运行的内存分为五个区域
栈stack 存储局部变量、函数参数、返回地址等自动管理函数调用时分配函数返回时释放栈空间从高地址向低地址增长栈大小有限过深的递归或者大数组可能导致栈溢出 堆区heap 用于动态分配内存由程序员手动管理分配和释放灵活但容易导致内存泄漏或碎片。堆空间从低地址向高地址增长。 数据段data segment 初始化数据段存储已初始化的全局变量和静态变量未初始化数据段BSS:存储未初始化的全局变量和静态变量这些变量在程序运行期间一直存在 代码段code segment/text segment 存储程序的机器代码编译后的指令只读不可修改包含函数、控制流等可执行代码
三、内存泄漏原因
在类的构造函数和析构函数中没有匹配的调用new和delete函数 在堆里动态分配内存给对象使用后未及时释放在构造函数中动态分配内存给成员在析构函数中未正确释放内存 没有正确的清除嵌套的对象指针 嵌套的对象指针指的是一个对象或数据结构中包含指向其他对象的指针 没有使用delete[] 释放通过 new[] 动态分配的数组内存缺少拷贝构造函数导致内存被重复释放 按值传递会调用拷贝构造函数引用传递不会调用。如果一个类里面有指针成员变量那么必须显式的写拷贝构造函数和重载赋值运算符反之则需要禁用拷贝构造函数和重载赋值运算符。 缺少重载赋值运算符函数的返回值是指针或引用类型但是指针指向的或引用的对象是局部变量导致返回值变成野指针。没有将基类的析构函数定义为虚函数 当基类指针指向子类对象时如果基类的析构函数不是虚函数那么子类的析构函数将不会被调用子类的资源没有正确是释放因此造成内存泄露。 析构的对象是 void* 类型 delete掉一个void*类型的指针导致没有调用到对象的析构函数析构的所有清理工作都没有去执行从而导致内存的泄漏
四、造成野指针的原因
指针变量没有被初始化指针被free或者delete后没有置为NULL指针操作超过了变量的作用范围比如返回指向栈内存的指针就是野指针。shared_ptr循环使用
五、常见解决办法
确保分配与释放配对使用智能指针C自动管理内存防止泄漏 shared_ptr共享的智能指针unique_ptr独占的智能指针 使用标准库容器如 std::vector、std::string代替手动分配的数组容器会自动管理内存。
六、参考文章
C 内存管理中内存泄漏问题产生原因以及解决方法