谁能详细解释一下new和delete的原理?

windywater 2006-11-04 09:13:51
比如说,如何搜索可用的堆内存?还有delete[]的时候,编译器是如何知道数组的大小的?
...全文
701 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
jedyi 2006-11-05
  • 打赏
  • 举报
回复
对内建数据类型,new 和 malloc作用差不多吧;对自定义类型的时候,new还调用了构造函数。

对于new/delete:
1. 对于内建数据类型,new出多大空间,delete的时候语言本身就能够正确释放。
2. 对于自定义数据类型(如类),new出的时间空间比类的大小要大一些,因为还需要记录一些额外信息(如内存大小等),delete的时候就根据这些额外信息进行。
houdy 2006-11-05
  • 打赏
  • 举报
回复
在C++中使用new来分配内存时,通过汇编我们可以看出,这里实际上先是调用operator new来分配适当大小的内存,然后再调用对象的构造函数初始化对象(当然如果时基本数据类型的话,就没有这一步)。根据现有查到的资料,operator new的内部是通过CRT中malloc来分配内存的。而在Windows平台下,malloc又是通过Win32 API中HeapXX()等内存管理函数来分配内存。而malloc中采用的内存管理算法,据我找到的资料,应该是一个叫Doug Lea写的算法,这里是介绍这个算法地址:http://gee.cs.oswego.edu/dl/html/malloc.html。
我在我的BLOG中写了一篇关于Windows平台不同内存分配函数之间的比较的文章:
http://blog.csdn.net/houdy/archive/2006/10/21/1344011.aspx
希望这里对你有些帮助:)
pcboyxhy 2006-11-05
  • 打赏
  • 举报
回复
这些都是操作系统的活
跟编译器没有关系
jwqu 2006-11-05
  • 打赏
  • 举报
回复
mark
jixingzhong 2006-11-05
  • 打赏
  • 举报
回复
参看文章 :
如何在linux操作系统下检测内存泄漏
http://linux.chinaitlab.com/administer/526436_2.html

第二部分 2.New和delete的原理
jixingzhong 2006-11-05
  • 打赏
  • 举报
回复
New和delete的原理

  当我们在程序中写下 new 和 delete 时,我们实际上调用的是 C++ 语言内置的 new operator 和 delete operator.所谓语言内置就是说我们不能更改其含义,它的功能总是一致的。以 new operator 为例,它总是先分配足够的内存,而后再调用相应的类型的构造函数初始化该内存。而 delete operator 总是先调用该类型的析构函数,而后释放内存(图1)。我们能够施加影响力的事实上就是 new operator 和 delete operator 执行过程中分配和释放内存的方法。

  new operator 为分配内存所调用的函数名字是 operator new,其通常的形式是 void * operator new(size_t size); 其返回值类型是 void*,因为这个函数返回一个未经处理(raw)的指针,未初始化的内存。参数 size 确定分配多少内存,你能增加额外的参数重载函数 operator new,但是第一个参数类型必须是 size_t.

  delete operator 为释放内存所调用的函数名字是 operator delete,其通常的形式是 void operator delete(void *memoryToBeDeallocated);它释放传入的参数所指向的一片内存区。

  这里有一个问题,就是当我们调用 new operator 分配内存时,有一个 size 参数表明需要分配多大的内存。但是当调用 delete operator 时,却没有类似的参数,那么 delete operator 如何能够知道需要释放该指针指向的内存块的大小呢?答案是:对于系统自有的数据类型,语言本身就能区分内存块的大小,而对于自定义数据类型(如我们自定义的类),则 operator new 和 operator delete 之间需要互相传递信息。

  当我们使用 operator new 为一个自定义类型对象分配内存时,实际上我们得到的内存要比实际对象的内存大一些,这些内存除了要存储对象数据外,还需要记录这片内存的大小,此方法称为 cookie.这一点上的实现依据不同的编译器不同。(例如 MFC 选择在所分配内存的头部存储对象实际数据,而后面的部分存储边界标志和内存大小信息。g++ 则采用在所分配内存的头 4 个自己存储相关信息,而后面的内存存储对象实际数据。)当我们使用 delete operator 进行内存释放操作时,delete operator 就可以根据这些信息正确的释放指针所指向的内存块。

  以上论述的是对于单个对象的内存分配/释放,当我们为数组分配/释放内存时,虽然我们仍然使用 new operator 和 delete operator,但是其内部行为却有不同:new operator 调用了operator new 的数组版的兄弟- operator new[],而后针对每一个数组成员调用构造函数。而 delete operator 先对每一个数组成员调用析构函数,而后调用 operator delete[] 来释放内存。需要注意的是,当我们创建或释放由自定义数据类型所构成的数组时,编译器为了能够标识出在 operator delete[] 中所需释放的内存块的大小,也使用了编译器相关的 cookie 技术。

  综上所述,如果我们想检测内存泄漏,就必须对程序中的内存分配和释放情况进行记录和分析,也就是说我们需要重载 operator new/operator new[];operator delete/operator delete[] 四个全局函数,以截获我们所需检验的内存操作信息。

iambic 2006-11-04
  • 打赏
  • 举报
回复
1.一般可用堆内存会组成一个可用空间的链表。
2.可以在申请的内存前放一块数据表示大小。
xiao2004 2006-11-04
  • 打赏
  • 举报
回复
到后来还是调用free 来玩玩吧。
lei001 2006-11-04
  • 打赏
  • 举报
回复
下面应该有内存管理理的机制,分配内存时会记录一下这次分配的大小等信息,释放时只要地址正确就可以了

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧