第一部分——基础部分

1.内存分配层次

C++ 申请内存分配:

1. CRT : malloc / free

2. C++ primitives : new , new[] , new() , ::operator new()

3. C++ Library : std::allocator

分配 释放 类别 能否重载
malloc() free() C函数 不能
new delete C++表达式 不能
::operator new() ::operator delete() C++函数
allocator<T> :: allocate() allocator<T>:: deallocate() C++标准库 可以自由设计来配置任何容器

2. 三个层次的基本使用

void *p1 = malloc[520];
free(p1);complex<int>* p2 = new complex<int>;      //一个对象
delete p2;void * p3 = ::operator new(520);          //520个字节,底层调用的就是malloc
::operator delete(p3);                    //底层调用的就是free    //以下是C++ 标准库提供 的 allocators.
//其接口虽然有标准规格,但是实现厂商并未完全遵守;下面为VC 和 GNU C 实现的差别。
#ifdef _VS_int* p4 = allocator<int>().allocate(10,(int*)0);     //allocate是非静态函数,需要通过对象来调用allocator<int>().dealloctate(p4,3);                  //deallocate也是是非静态函数,需要通过对象来调用
#endif
#ifdef _GUNC2.9__void* p4 = alloc::allocate(512);                     //这两个函数都是静态的,可以通过全名调用它们,以下分配512bytesallco::deallocate(p4,512);
#endif#ifdef _GNUC4.9__void * p4 = allocator<int>( ).allocate( 7 );        //gcc 4.9 中空间配置器(allocator)的实现向标准看齐了allocator<int>( ).deallocate( (int*) p4 , 7 );      //allocate 和 deallocate 都是非静态函数,需要通过对象来调用

3. 中间层次的底层实现 ( new , new[] , new() , ::operator new() )

(1) new 和 delete

① new 作用:申请分配内存并调用构造函数

 Complex* pc = new Complex(1,2);//编译器转为下面的代码Complex* pc;try{void* mem = operator new( sizeof(Complex));  //申请堆区内存pc = static_cast<Complex*> (mem);pc->Complex::Complex(1,2);          //只有一部分编译器才可以像左边这样直接调用构造函数
}
catch( std::bad_alloc ){}

上述代码中的operator new 函数 如下:

  void* operator new(size_t size , const std::nothrow_t&) _THROW0()
{void* p;while((p = malloc(size))==0 )    //malloc{....}return (p);
}

可见,从 new 到 operator new ,最终我们发现调用的还是malloc函数。

② delete 作用:释放内存 并 调用析构函数

 Complex* pc = new Complex(1,2);...
delete pc;
//编译器转为pc->~Complex();        //析构
operator delete(pc);   //释放内存

上述代码中的operator delete 函数 如下:

  void __cdecl operator delete(void *p) _THROW0()
{free(p);
}

可见,从 delete 到 operator detele,最终我们发现调用的还是free函数。

(2) array new , array delete

① array new

Complex* p = new Complex[3];
//调用了三次 默认构造函数
...
delete[] p;
//调用了三次 析构函数

这里重点说明一个问题:用array new 出来的指针,在对其进行delete释放内存时,如果不加"[]" 会怎么样

答:delete 的作用是 先调用析构函数,再释放掉之前申请的内存,当你要释放的内存里的对象的析构函数不重要时(也就是说对象内部没有申请新的堆区内存),有无"[]"将没有差别;但是当对象的析构函数重要时(对象内部申请了堆区内存),不添加"[]"将会导致只调用一次析构函数,当申请的内存中存储了n个对象,就会导致n-1个对象无法调用自己的析构函数,这些对象中的指针所指向的堆区内存将无法被释放(因为没有调用析构函数),进而导致内存泄漏。

(3) placement new

placement new 可以用来对已申请的内存通过构造函数来产生对象。因此,没有placement delete ,因为 placement new 没有分配内存。

include <new>delete [] buf;char* buf = new char[ sizeof( Complex )*3 ];
Complex* pc = new( buf )Complex(1,2);                //调用构造函数
//上面这一行代码 编译器转为如下代码
Complex* pc;
try{void* mem = operator new( sizeof( Complex) , buf );pc = static_cast<Complex*> (mem);pc->Complex::Complex(1,2);
}
catch( std::bad_alloc ){}
...

static在内存层面的作用_C++内存管理笔记相关推荐

  1. static在内存层面的作用_虚拟地址空间--用户进程看到的自己所占用的内存

    我们知道内核管理物理内存,其实除了管理本身内存外,还必须管理用户空间中进程的内存,我们称这个内存为进程地址空间,也就是系统中每个用户空间进程所看到的内存. 传统的C语言编译出来的进程地址空间包含哪些对 ...

  2. static在内存层面的作用_static关键字总结

    static,即静态声明.它在 作用域.存储方式.生命周期 等各方面影响一个变量或函数.文章将从 局部变量.全局变量.普通函数.类的static成员(包括数据成员与成员函数)来总结static. 全局 ...

  3. static在内存层面的作用_「C++ Primer plus 心得」9.内存模型和名称空间

    本章内容包括: 单独编译 存储持续性.作用域和链接性 定位new运算符 名称空间 C++ 为在内存中存储数据方面提供了多种选择.可以厅数据保留在内存中的时间长度(存储持续性)以及程序的哪一部分可以访问 ...

  4. static在内存层面的作用_static的作用和内存划分?

    有时希望函数中的局部变量的值在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,在下一次再调用的时候该变量已经有值.这时就应该指定该局部变量为静态变量,用关键字 static 进行声明. ...

  5. java中的hashcode方法作用以及内存泄漏问题

    本文装载:http://hi.baidu.com/iduany/item/6d66dfc9d5f2da1650505870 hashCode()方法的作用&使用分析 一直以来都想写篇文章来说明 ...

  6. java static内存泄漏_Java中的内存泄漏

    内存泄漏是指不再使用的对象持续占有内存空间而得不到及时释放,从而造成内存空间的浪费称为内存泄漏.比如,长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是 ...

  7. java弱引用(WeakReference)和SoftReference的区别以及在android内存处理的作用

    http://mingnjintian-163-com.iteye.com/blog/1120472 weakReference一般用来防止内存泄漏,要保证内存被VM回收 softReference的 ...

  8. .net调用c++方法时如何释放c++中分配的内存_C/C++编程笔记:C语言编程知识要点总结!大一C语言知识点(全)...

    一.C语言程序的构成 与C++.Java相比,C语言其实很简单,但却非常重要.因为它是C++.Java的基础.不把C语言基础打扎实,很难成为程序员高手. 1.C语言的结构 先通过一个简单的例子,把C语 ...

  9. java内存屏障详解_一文读懂Java关键词之volatile作用(内存屏障)

    之前在一篇文章中跟大家一同学习了CPU缓存一致性,通过缓存一致性协议MESI我们可以让CPU各个计算核心中缓存的数据保持一致,避免造成计算结果的差异. 我们还知道Java内存模型中,各个线程还保存了一 ...

最新文章

  1. Chapter 4 Invitations——4
  2. 【CyberSecurityLearning 36】靶场环境搭建(ubuntu系统安装优化及vulhub安装)
  3. python lamda函数_python 用lambda函数替换for循环的方法
  4. 专访阿里云专有云马劲,一个理性的理想主义者
  5. 基于 Apache Mahout 构建社会化推荐引擎
  6. sicily 1002. Anti-prime Sequences
  7. php ob系列的函数
  8. 关于自走棋类游戏棋子搜索算法分析
  9. scrapy框架爬虫
  10. unity 导入gltf_GLTF相关资料
  11. 结合北斗PPP_B2b 导航电文进行精密定位(PPP)
  12. 大数据框架基础Hive安装
  13. 5G关键技术之波束成型
  14. Java实现 兔子数问题
  15. 【荐读】基于文本数据的消费者洞察
  16. 港科科研 | 香港科大成立亚洲首个跨国人工智能芯片设计研发联盟
  17. Intellij中maven项目使用junit时,遇到的问题
  18. 《深入浅出Docker》学习笔记
  19. python对比两张图片找不同
  20. Arduino练习三——PWM 调控灯光亮度实验

热门文章

  1. 2017.9.19 Gcd 思考记录
  2. 机械学哪种计算机语言,对于机器学习,到底该选择哪种编程语言?
  3. 【英语学习】【Level 07】U01 Making friends L2 A new friend from the past
  4. 80386/386/Intel386 架构/流水线及其优化
  5. Android中VectorDrawable与SVG
  6. Unity Shader: 理解Stencil buffer并将它用于一些实战案例(描边,多边形填充,反射区域限定,阴影体shadow volume阴影渲染)
  7. Apple发布watchOS 5 Beta 9
  8. 利用xlwt、xlrd搜索excel表格内容并复制出需要的那一行内容
  9. 常用的linux文件权限
  10. SQL Server 2012安装配置(Part2 )