C++ 避免内存泄漏

本文详细介绍了C++中内存泄漏的原因、类型以及如何避免和检测内存泄漏。重点强调了栈和堆的区别,手动分配内存可能导致的泄漏问题,并提供了防止内存泄漏的编程原则,如使用引用传参,确保构造函数与析构函数中内存分配与释放的匹配,以及使用特定工具进行内存泄漏检测。
摘要由CSDN通过智能技术生成

内存泄漏

前面我们讲过,分配了一个内存块但是忘记释放这个内存块会导致严重的问题,这样的内存块将等到程序执行结束时才会被释放

如果这个程序运行很长时间(例如服务器,而且不是所有的操作系统都像windows一样每天都可以重启)且这个程序在运行过程中不断的申请新内存块(new),如果此时忘记释放那些已经不在使用的老内存块,老内存块将迟早将内存消耗殆尽,直接导致后边的new操作无法执行和程序崩溃

这样的编程漏洞称作内存泄漏(memory leak)

作为 C++ 程序员,内存泄露始终是悬在头上的一颗炸弹。在过去几年的 C++ 开发过程中,由于我们采用了一些技术,我们的程序发生内存泄露的情况屈指可数。今天就在这里向大家做一个简单的介绍


内存是如何泄漏的

在c/c++的程序内存分配中,自顶向下分为代码段,数据段,栈区,栈保留区,动态链接库区,堆保留区,堆区.

C++程序中,主要涉及到的内存就是[堆Stack][栈Heap]

栈区(stack) :由 编译器自动分配和释放,存放的是 运行时函数分配的局部变量,函数参数,返回数据,返回地址等参数,其操作类似于数据结构中的栈。
堆区(heap):一般 由程序员手动分配,如果程序员没有释放,程序结束时可能由os回收,其分配类似于链表,手动分配的内存便是在堆中的

详见C++内存分配一文:https://blog.csdn.net/Chroniccandy/article/details/109053967

栈中内存的申请和释放:
通常来说,一个线程上的栈内存是有限的,通常为8MB左右(大小取决于运行环境),栈上的内存通常是由编译器自动管理的。当在栈上分配一个新的变量时,或进入一个函数时,栈的指针会向下移动(下压栈),相当于在栈上分配了一块内存。我们把变量分配在栈上,也就是利用了栈上的内存空间,当这个变量的生命周期结束的时候,栈的指针会上移,相当于回收了此块内存。

正是由于栈上的内存和分配和回收均是由编译器自动完成控制的,所以在上是不会发生内存泄漏的,只会发生栈 溢 出的情况(Stack Overflow),也就是分配的空间超过了规定的栈大小。

堆中内存的申请和释放:
堆中的内存是由程序直接控制的,程序可以通过[new/delete]来分配和回收内存,如果程序中通过[new]手动分配了一块内存,但忘记使用[delete]来回收内存,便会发生内存泄漏。


内存泄漏的常见类型

内存的泄漏可以分为四类:

1.常发性内存泄漏
即发生内存泄漏的代码会被多次重复的指执行,每次被执行的时候都会导致一块内存泄漏

2.偶发性内存泄漏
即发生内存泄漏的代码只有再某些特定环境和操作过程下才会发生(例如在释放分配的内存之前程序通过某条件跳出了函数体,导致内存无法被delete)。常发性和偶发性是相对的,对于特定的环境,偶发性的也许会变成常发性的,所以测试环境和测试方法对检测内存泄漏至关重要!

3.一次性内存泄漏
即发生内存的代码只会被执行一次,或者是由于算法上的缺陷,导致总会有且仅有一块内存发生泄漏(比如在类的构造函数中分配内存,在析构函数中却没有释放该内存,但是由于这个类只会使用一次,所以内存泄漏只会发生一次)

4

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值