1. 使用new动态分配内存:若没有足够内存,则new返回0(空值指针null pointer);
2. 不要使用delete释放不是new分配的内存,delete释放指针指向的内存,但不会删除指针本身;
3、对空值指针应用delete是安全的;
4、创建数组时的静态联编与动态联编:数组声名int a[10], 静态联编,数组的长度在编译时确定;
     用new[]创建数组,动态联编,运行时为数组分配内存空间。动态-运行时分配内存。

C++有3种管理数据内存的方式:自动存储、静态存储、动态存储(自由存储空间或堆)(三块独立的内存)

自动存储:(auto /  register ) 自动变量的持久性为自动的,在程序开始执行其所属的函数或代码块时创建,执行                   完后释放。
                     auto: in stack LIFO 
                    register: in CPU register,使用寄存器处理变量,提高访问速度;没有内存地址,不能用&取地址。
静态存储:(global / static ) 在程序整个运行期间都存在. (外部链接性、内部链接性、无链接性)
                    初始化为0。
     int  global = 1000;  //外部链接性,可在程序的其他文件使用, 使用时要用extern声名  (外部变量/全局变量)
    static int one_file = 50; //内部链接性,只能在本文件使用   (函数如果为static也一样,只能在该文件中被调)
    int main(){      ...  }
    void func(){
         static int count = 0;  //静态局部变量,只在该代码中可用,但它在该代码不活动时始终存在。
   }
    可用extern重新声名以前定义过的外部变量;
    访问被隐藏的外部变量(被局部变量隐藏了):用作用域解析符(::)::n 表示使用n的全局版本
   const char * const months[12] = {"Jan", "Feb", "Mar",...};
 //第一个const防止字符串被修改,第二个const确保数组中每个指针始终指向它最初指向的字符串。
    mutable限定符:const/volatile/mutable  const禁止修改结构成员,但是mutable使const结构中的成员不受这种限制
     struct data { char name[30];  mutable int accesses;  };
     const data  a = {....};  strcpy(a.name, "fdsf"); //not allowed    a.access++//allowed
     外部定义的const数据的链接性为内部的,跟static一样

动态存储:(free store / heap)  new/delete,  malloc/free
  1、使用new来设置指针的语句必须位于函数中,因为只能使用常量表达式来初始化静态存储变量:
       float * p;
       //float *p = new float[20]; //initialization with non-const not allowed here
        main (){   p = new float[20];  }
   2、布局new操作符 (placement new): 自己指定空间为placement new提供内存空间,而不是在heap中分配
      #include<new>
      char buffer[512];
       ......double *pd1, *pd2;
             pd1 = new double[N];
             pd2 = new (buffer) double[N];
注:不能用delete [] pd2; 来释放分配的内存,buffer指向的内存是静态的,delete只能用于指向常规new分配的堆        内存(free store)

内存泄漏(memory leak)- 被分配的内存再也不能使用了,也无法回收
                                             (new和delete使用不恰当,没有配对使用而产生)
       如果使用new操作符在自由存储空间上创建变量后,没有调用delete,则即使包含指针的内存
由于作用域和对象生命周期的原因而被释放,在自由存储区动态分配的变量或结构也将继续存在,
这样,将无法访问free store空间中的结构,因为指向这些内存的指针无效,因此这些被分配的内存
将无法使用,从而导致内存泄漏。

一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显示释放的内存。应用程序一般使用malloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了

检测内存泄漏的关键是要能截获住对分配内存和释放内存的函数的调用。截获住这两个函数,我们就能跟踪每一块内存的生命周期,比如,每当成功的分配一块内存后,就把它的指针加入一个全局的list中;每当释放一块内存,再把它的指针从list中删除。这样,当程序结束的时候,list中剩余的指针就是指向那些没有被释放的内存。这里只是简单的描述了检测内存泄漏的基本原理,详细的算法可以参见Steve Maguire的<<WritingSolid Code>>。
如果要检测堆内存的泄漏,那么需要截获住malloc/realloc/free和new/delete就可以了(其实new/delete最终也是用malloc/free的,所以只要截获前面一组即可)。对于其他的泄漏,可以采用类似的方法,截获住相应的分配和释放函数。比如,要检测BSTR的泄漏,就需要截获SysAllocString/SysFreeString;要检测HMENU的泄漏,就需要截获CreateMenu/DestroyMenu。(有的资源的分配函数有多个,释放函数只有一个,比如,SysAllocStringLen也可以用来分配BSTR,这时就需要截获多个分配函数)

C++中的内存管理(new、delete、内存泄漏)相关推荐

  1. C++:内存管理:C++内存管理详解

    C++语言内存管理是指:对系统的分配.创建.使用这一系列操作.在内存管理中,由于是操作系统内存,使用不当会造成很麻烦的后果.本文将从系统内存的分配.创建出发,并且结合例子来说明内存管理不当会造成的结果 ...

  2. 属性与内存管理(属性与内存管理都是相互关联的)

    <span style="font-size:18px;"> 属性与内存管理(属性与内存管理都是相互关联的)第一部分一,属性:属性是OC2.0之后出来的新语法,用来取代 ...

  3. 【Linux 内核 内存管理】优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )

    文章目录 一.禁止 / 开启内核抢占 与 方法保护临界区 二.编译器优化屏障 三.preempt_disable 禁止内核抢占 源码 四.preempt_enable 开启内核抢占 源码 一.禁止 / ...

  4. JVM自动内存管理机制——Java内存区域(下)

    一.虚拟机参数配置 在上一篇<Java自动内存管理机制--Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...

  5. Java内存管理:Java内存区域 JVM运行时数据区

    Java内存管理:Java内存区域 JVM运行时数据区 在前面的一些文章了解到javac编译的大体过程.Class文件结构.以及JVM字节码指令. 下面我们详细了解Java内存区域:先说明JVM规范定 ...

  6. 鸿蒙系统内存管理,嵌入式系统内存管理-鸿蒙HarmonyOS技术社区-鸿蒙官方战略合作伙伴-51CTO.COM...

    1.概述 操作系统的内存管理功能用于向操作系统提供一致的地址映射功能和内存页面的申请.释放操作.在嵌入式实时系统中,内存管理根据不同的系统,有不同的策略,对于有些系统支持的虚拟内存管理机制,对于另外一 ...

  7. 【C 语言必知必会】内存管理、动态分配内存、野指针

    C 语言内存管理.动态分配内存.野指针 文章目录 C 语言内存管理.动态分配内存.野指针 前言: 1.内存分区 1.1 代码区 1.2.1 全局初始化数据区(静态数据区data段) 1.2.2 未初始 ...

  8. 【Linux 内核 内存管理】内存管理架构 ⑤ ( sbrk 内存分配系统调用代码示例 | 在 /proc/pid/maps 中查看进程堆内存详情 )

    文章目录 一.sbrk 内存分配系统调用代码示例 二.在 /proc/pid/maps 中查看进程堆内存详情 本篇博客调用 sbrk 系统调用函数 , 申请并修改 堆内存 , 并在 /proc/pid ...

  9. 深入理解PHP内存管理之谁动了我的内存

    本文地址: http://www.laruence.com/2011/03/04/1894.html 转载请注明出处 首先让我们看一个问题: 如下代码的输出, var_dump(memory_get_ ...

  10. linux-glibc内存管理小结2(内存相关系统调用的实现)

    在上一节ptmalloc源码分析中我们提到dlmalloc向系统申请内存的方式有两种, 对应Linux系统下分别是sbrk()与mmap()系统调用. 本节我们就来看下brk()/sbrk()与mma ...

最新文章

  1. C++ STL: 超详细 容器 deque 以及 适配器queue 和 stack 源码分析
  2. 数据库基础笔记(MySQL)5 —— 基础索引
  3. 使用Intel VTune性能分析器分析.NET模块运行时间
  4. HTML5的Canvas画图模拟太阳系运转
  5. 会玩!格力公开“磁悬浮床垫”专利
  6. asp.net 读取mysql_ASP.NET连接数据库并获取数据
  7. SQL语言中的连接表
  8. 给小伙伴们的json数据
  9. 华为android10手机指纹,华为P10这些指纹功能你知道几个?
  10. android 获取摄像头像素
  11. 【转载】配置文件 .yml 写法小结
  12. 计算机word做课程表实验报告,《用word做课程表》教学设计
  13. 秒(s) 毫秒(ms) 微秒(μs) 纳秒(ns) 皮秒(ps)及Java获得
  14. 1000美元实现自动驾驶,他是侠客还是极客?
  15. c语言编程使蜂鸣器音乐,求: 用51单片机c语言操作使蜂鸣器奏出“祝你生日快乐”音乐的全部程序!...
  16. android防丢器设计,蓝牙防丢器 安卓代码和附带说明
  17. 用python对excel中一列的时间数据更改格式
  18. bootstrap实现单页面跳转_bootstrap-table.js增加跳转到xx页功能实现方法
  19. 使用.Net分析.Net达人挑战赛参与情况
  20. 如何用计算机复印,hp复印一体机怎么使用 hp复印一体机使用方法【详解】

热门文章

  1. 递归删除单链表中所有值为x的元素_如何纯递归反转链表的一部分
  2. 排序算法之计数排序、基数排序和桶排序
  3. 18.图像用户界面入门:EasyGui
  4. 【opencv】3.在一个opencv窗口中显示多个视频界面、画箭头、画掉头箭头
  5. fatal error C1083: 无法打开预编译头文件:“Debug\opencv.pch”: No such file or directory
  6. Zookeeper集群脑裂问题
  7. MySQL优化器:index merge介绍
  8. 把技术卖给不懂技术的人
  9. log4j2配置文件的故事
  10. JAVA访问控制符(写给初学者的)