yifangzhuhou

导航

今日刷题总结20

C++的内存布局

在C++中内存被分为5个部分,分别是堆、栈、自由存储区、全局/静态存储区以及常量存储区。

自由存储区与堆的区别

堆是C语言和操作系统里的术语,它是由操作系统维护的一块特殊的内存,当C程序调用malloc函数进行动态内存分配时就是从堆上获取内存的,而调用free函数可以交还分配的内存。自由存储区是C++基于new和delete操作符的一个抽象概念,凡是通过new来申请的内存区域都可称为自由存储区。几乎所有的C++编译器默认都使用堆来实现自由存储区,即缺省的全局库函数operator new和operator delete也是按照malloc和free的方式来实现的,这时使用new操作符分配的对象,说它在堆或者自由存储区上都可以。不过operator new和operator delete是可以被重载的(自定义版本必须位于全局作用域或者类作用域中),可以使用其他内存来实现自由存储,比如静态存储区,这时自由存储区和堆就不是一个概念了。

new和malloc的区别,delete和free的区别

1)是否调用构造/析构函数

使用new表达式时会执行3步操作:

a)new表达式会调用一个名为operator new(或operator new[])的标准库函数。该函数分配以一块足够大的,原始的,未命名的以便存储特定类型的对象(或对象数组)。

b)编译器运行相应的构造函数以构造对象,并为其传入初始值。

c)对象构造完成以后返回一个指向该对象的指针。

使用delete表达式时会执行2步操作:

a)delete表达式会调用对象的析构函数。

b)编译器调用名为operator delete(或operator delete[])的标准库函数释放内存空间。

而malloc/free只是单纯地分配和释放内存空间,不会调用构造/析构函数。

2)返回类型的安全性

new操作符分配内存成功后,返回的是类对象类型的指针,不需要进行类型转换,所以new操作符是类型安全的。而malloc内存分配成功返回的是void*,需要进行强制类型转换换成需要的类型指针。

3)内存分配失败时的返回值

malloc内存分配失败时会返回NULL,而new不会,它会抛出bad_alloc异常。

4)是否需要指定内存大小

调用new操作符进行动态内存分配时无需指定内存大小,编译器会根据类型信息自行计算,而malloc需要显式地指定所需内存的大小。

5)是否可以被重载

operator new和operator delete可以被重载,标准库定义了operator new和operator delete的8个重载版本,如下所示

//这些版本可能抛出异常

void *operator new(size_t);//分配一个对象

void *operator new[](size_t);//分配一个对象数组

void *operator delete(void *) noexcept;//释放一个对象

void *operator delete[](void *) noexcept;//释放一个对象数组

//这些版本承诺不会抛出异常

void *operator new(size_t, nothrow_t&) noexcept;

void *operator new[](size_t, nothrow_t&) noexcept;

void *operator delete(void *, nothrow_t&) noexcept;

void *operator delete[](void *, nothrow_t&) noexcept;

应用程序可以自定义上面函数版本中的任意一个,前提是自定义的版本必须在全局作用域或类作用域,当把它们定义为类成员函数时,它们是隐式静态的。malloc/free不允许重载。

参考自http://blog.jobbole.com/102002/

http://www.cnblogs.com/QG-whz/p/5060894.html

posted on 2017-09-10 11:30  yifangzhuhou  阅读(113)  评论(0编辑  收藏  举报