想确切的知道C++的delete到底是如何工作的 希望牛人指点一二

ziplj 2010-12-24 12:15:11
今天上班比较闲 想研究一下一直以来比较困惑的问题 就是 new的时候传入了一个大小的参数
但是delete的时候 却不需要参数
上网找了一下 类似于这种
http://blog.csdn.net/sanglipeng/archive/2006/10/24/1348500.aspx
里面所说

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

我自己在VS2008中写了一个Test程序

struct Test1
{
char* pTest;
int iX;
int iY;
};

struct Test2
{
char szTest[128];
char szTest2[2];
};
void CMFCTestDlg::OnBnClickedOk()
{
Test1* pTest = new Test1;
Test2* pTest2 = new Test2;
delete pTest;
delete pTest2;
}

以第一个pTest为例 发现内存中的值是
cd cd cd cd cd cd cd cd cd cd cd cd fd fd fd fd ab ab ab ab ab ab ab ab ee
fe ee fe ee fe ee fe 00 00 00 00 00 00 00 00 10 00 0a 00 74 07 18 00 00 00
是在看不见 也不看不懂VC是如何给new的内存后面增加Cookie信息的
原本以为是Debug的问题 我在Release下面也测试了一下
Dump出来的内存是
0d f0 ad ba 0d f0 ad ba 0d f0 ad ba ab ab ab ab ab ab ab ab ee fe ee fe 00
00 00 00 00 00 00 00 db 03 05 00 ee 14 ee 00 78 01 39 00 78 01 39 00 ee fe
也没有发现想要的信息


跪求牛人解释一下 如何查看这种信息
...全文
599 39 打赏 收藏 转发到动态 举报
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
yutaooo 2010-12-25
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 libinfei8848 的回复:]
就是申请的实际内存比需要的内存大一点
是以为内存分配以页大小为单位,申请内存大小是页的向上整数倍
[/Quote]

你这个是不正确的。

ec++中说,new会有一些薄记工作。
LZ写了“此方法称为 cookie”
有些资料会说,元数据。

这些都是一回事。应用通过new或malloc()向分配器请求内存,分配器交给用户的内存块,叫做有效负载。有效负载是分配器分配出来内存块中的一部分。分配器实际上要分配稍大一些的内存块。比有效负载大多少呢?各个实现可以不同。比如,M$的可以和glibc的不同。大出来的那些内存块被分配器自己使用,应用程序是不使用的,虽然有些黑客程序的确访问这些本应只由分配器用的信息来实现特殊功能。里面一般存放的是,当前块是否使用的标志,当前这个块的大小等信息。delete之所以可以不用带一个尺寸信息的参数,那是因为,“当前这个块的大小信息”已经指出了需要释放多大的内存块,到空闲链中。而这个信息就是在new的时候,被薄记进入元数据的。

应用程序一般使用小额的内存块,这于内核中的内存分配器不同。内核中的确有以页为单位分配内存的分配器。但,这不适用于应用层,不然要有多少内存被闲置呀。
ziplj 2010-12-25
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 libinfei8848 的回复:]

就是申请的实际内存比需要的内存大一点
是以为内存分配以页大小为单位,申请内存大小是页的向上整数倍
[/Quote]自己参看13L
ziplj 2010-12-25
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 yutaooo 的回复:]
给楼主建议,不要在c++的delete上追寻答案。要从malloc() free()中探索。这是因为,delete定义的是语意,找不到实现。而malloc() free()可以找到实现,能明明白白的告诉你某个实例如何产生效果。当了解清楚了某个分配器的实现,那么,其它的分配器在概念上是一样的。

我对分配器的了解,是从CSAPP中开始的。建议LZ也看看CSAPP的相关章节。

之后,看一下早……
[/Quote]Thanks Debug下一直单步跟踪就可以跟踪到Debug下的Cookie的数据结构
Meteor_Code 2010-12-24
  • 打赏
  • 举报
回复
new开出来的空间尺寸信息和地址信息是系统在内存管理目录中保存的,大家不用操心,至于new出来的信息到底是什么,我知道一点
Release下,是完全随机的东西,没有意义,道理很简单:上次使用这快内存时留下的,也可能是系统的某些动作留下的
debug下,申请出来的空间全部被初始化为cd,其实应该说把能够分配的空间都初始化为cd了,你申请的只不过他没有清理而已
cd其实是机器码:int 3;就是调试中断,这是唯一一个可以在保护模式下任意使用的中断.vc的调试器负责完成这个中断.他把debug的数据始化为cd,就是在你的程序崩溃,发生错误的转移时可能转移到这些内存上,然后马上int3,就进入了他的调试器.
而Release下根本没有调试器始化为cd没意义.
所以在调试情况下检查空指针还应该判断0xcdcdcdcd,这样的数据.
这是我知道的一点,不知到对LZ是否有用
龙哥依旧 2010-12-24
  • 打赏
  • 举报
回复
用zhao1zhong4的话,看看汇编就知道了,调试环境atl+8!
不过我觉得你的确是闲的,C++程序员研究它干啥?
:)
feng4206yu 2010-12-24
  • 打赏
  • 举报
回复
如果不知道cookie信息结构,当然什么都看不出来.
job82824 2010-12-24
  • 打赏
  • 举报
回复
我觉得可以这样理解。new操作就是把堆中的一些空间标记下,告诉编译器这些空间已经在用了,下此再new的时候就不会重叠在一起了;delete就是把这些空间的标记去掉了,让它们回到未分配的堆中,告诉编译器这些空间又可以再用了。动态分配内存空间时要考虑字节对齐的问题,否则就可能内存泄露了。
libinfei8848 2010-12-24
  • 打赏
  • 举报
回复
就是申请的实际内存比需要的内存大一点
是以为内存分配以页大小为单位,申请内存大小是页的向上整数倍
赵4老师 2010-12-24
  • 打赏
  • 举报
回复
heapwalk
pwalk
pwalker
赵4老师 2010-12-24
  • 打赏
  • 举报
回复
《Windows核心编程》
《深入解析Windows操作系统-Windows Internals》
yutaooo 2010-12-24
  • 打赏
  • 举报
回复

给楼主建议,不要在c++的delete上追寻答案。要从malloc() free()中探索。这是因为,delete定义的是语意,找不到实现。而malloc() free()可以找到实现,能明明白白的告诉你某个实例如何产生效果。当了解清楚了某个分配器的实现,那么,其它的分配器在概念上是一样的。

我对分配器的了解,是从CSAPP中开始的。建议LZ也看看CSAPP的相关章节。

之后,看一下早期分配器的设计原理。一篇非常著名的文档描述了这些原理。我的第二步是看的这个,因为它概念比较简洁,没有牵扯到目前的多线程环境下的lock-free编程之类繁琐的内容。链接是:http://g.oswego.edu/dl/html/malloc.html

再后面,看一些黑客方面资料吧。熟悉一些应用。比如堆溢出什么的。

再再后面,也许是最新版本glibc中分配器的实现。我是没敢看,这个一定是非常繁琐的,我计划是把并发算法学习到一定程度再仔细去看的。

new delete是c++的内存分配期,本质上就是分配算法的具现,这些算法有专门的书籍描述,什么首次适配,最优适配等等。再加上,现在又把并发编程提到了一定高度,并行算法也加入了分配器实现。总的来说,学好分配算法+并发算法就是实质。

另外,关于0xcdcd这些东西。真要深究,也许会走到系统层哦。
lzfbird 2010-12-24
  • 打赏
  • 举报
回复
研究一下还是可以的。不过不开发操作系统的话,一般用不着考虑这么多。

taodm 2010-12-24
  • 打赏
  • 举报
回复
不要试图深究这东西,其它值得多花时间学的东西多着呢。
hw_henry2008 2010-12-24
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 ziplj 的回复:]

Debug模式下 VC 申请内存 本质上还是调用HeapAlloc来完成内存的申请
因此 由于Windows源码问题 研究下去基本无解 而且如果OS来做这种事情 上面的疑惑感觉就不是太难理解了 以我个人感觉而言 delete的工作流程应该不是Blog里面说的那样 而是全部由OS来管理了 new出来的大小根本就不在new的内存的前面 或者后面

以下所说均在Debug模式下
虽说结果不是……
[/Quote]

正解,再微软面试题里见过
gules 2010-12-24
  • 打赏
  • 举报
回复
这个所谓的cookie确实是平台及运行时库实现相关,研究它没有什么普遍(通用)实际意义,知道有这个机制就行了;最多也只能说是针对某一特定平台学习内存管理机制罢了。
  • 打赏
  • 举报
回复
去看看windows核心编程 有一章专门讲这个的,很不错
无言猪 2010-12-24
  • 打赏
  • 举报
回复
要看你的CRT堆分配模式,通常是系统模式。也就是new实际是直接jmp到RtlAllocateHeap,delete直接到RtlFreeHeap.然后在Release模式下,你得到的地址-8就是这块内存的head地址,也就是_HEAP_ENTRY,前2个字节就是你这块内存地址的大小,要乘以粒度系数,一般是8.
  • 打赏
  • 举报
回复
好吧,我没有深入了解过。。
  • 打赏
  • 举报
回复
new出的内存要大于申请的内存!多出来的用于存放这块内存标识,比如大小等!

这样在delete的时候就不用给大小,而直接在new出来的那块内存开头去查看,便可知道需要释放掉多少内存!
Defonds 2010-12-24
  • 打赏
  • 举报
回复
内存分析
加载更多回复(13)
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质?你是否成为一名资深开发人员,开发别人做不了的高性能程序?你是否经常要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹? 那么C++就是你个人能力提升,职业之路进阶的不二之选。【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。2.带你从知识与思的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署;2.吊打一切关于C++的笔试面试题;3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块基础篇本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。进阶篇本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。提升篇:本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。
本课程是C++零基础入门课程,一共19个大章节,课件内容大概10万字,会尽量详细系统的把C++讲清楚,由于C++有一部分知识点和C语言重合,本课程也附带讲解C语言的知识点,学习本课程是同时掌握两门语言,前10章是C和C++的共同部分,如果出现二者的区别会分开讲解。本课程不会盲目的讲解C++语法,将会和Google开源C++项目WebRTC结合,介绍C++在实际项目中的应用,在部分章节会提供相应的算法题目巩固本章节的内容。除了C++的学习,本课程会提供一些软件开发的经验、方法,让大家少走一些弯路。C++虽然难学,但是也不是学不会,掌握好了C++,学习其它语言将会更轻松、愉快。课程章节内容概述第1、2、3、4、5章节作为C/C++基础,主要以理解为主,可以花费较少的时间;第6~~10章节讲解指针、内存管理、函数,需要多理解练习;第11章是C++的核心,类与对象;第12章,讲解C++的精华部分模板元编程;第13章节讲解C++的智能指针,这是C++程序设计的重要技术,需要多理解、练习;第14章C++标准库,以应用为主会稍微简单些;第15章介绍C++新标准中比较实用的知识点,会比较难,不好理解,需要勤加练习;第16章文件读写以练习为主,较简单;第17章多线程以理解练习为主,可以参考开源项目学习、应用。第18、19章主要是C++领域介绍,职业选择,C++学习方法推荐。第1章是C/C++历史、版本介绍、C++难点痛点分析、学习网站推荐、书籍推荐。第2章介绍C++开发环境搭建以及项目构建方法,调试方法,这是C++学习的第一步,是很关键的一步;本章主要介绍三种开发环境的安装与项目构建方法: (1)Windows Visual Studio C++ 开发环境; (2)Virtual Box虚拟机ubuntu C++ vscode ssh开发环境; (3)Windows WSL : windows linux子系统。课程会同时介绍在windows和linux下的C++开发,windows以vs2022为开发环境,linux以ubuntu vscode ssh gcc g++为代码编写环境。第3章是C++入门知识点讲解,数据类型,变量、输入输出、运算符等,该部分以理解记忆为主,可以快速学完。第4章讲解循环控制,if、for、while、do while、go。第5章是数组,讲解一维数组,二维数组,并提供了一些练习题,供学习巩固。第6章是指针与引用,该部分是C/C++学习的难点,也是众多C/C++程序员的噩梦,指针与引用内容是函数的基础,因此提到前面来。第7章讲解字符串,字符串是一个很复杂的数据类型,在C++中更是复杂,由于C++应用范围广,几乎每个C++框架都有自己的字符串实现方式,C++的字符串因此至少有十多种表现方式,因此我考虑把字符串作为单独章节,让大家在以后的开发中增加对字符串的理解。第8章是内存分配,独立分配释放内存,也是C/C++区别其它语言的地方,程序员可以直接操作内存,但同时也为程序的编写带来了难度,内存管理不好,很容易出现程序无法商用的情况。除了基础的内存分配,本章节也会介绍内存池,为编写高性能C++程序打基础。第9章讲解函数,有了前面八章的铺垫,编程中的重要成员函数出现了,这一章的内容会稍微难些,要注意理解、练习,章节的最后提供了练习题,供学习巩固。第10章介绍结构体,在C语言中,结构体应用很广泛,这也是C语言结束的章节。第11章类与对象是C++的核心,本章的知识会比较多,会详细介绍类的各个知识点,名字空间、函数重载、构造函数、析构函数、深拷贝、浅拷贝、静态函数、继承、虚函数、多态、友元函数、友元类、运算符重载、类内存分析等等。第12章是模板元编程是C++最难的内容,也是写C++高性能程序的必经之路,模板元编程也是后面智能指针、标准库STL、多线程的基础。第13章讲解智能指针,会由浅入深的讲解内存分配释放与智能指针的关系,会全面介绍C++智能指针的应用。一个好的C++项目,基本是看不见new与delete,该章节会介绍一部分webrtc中的代码,看看优秀的C++项目是怎么写C++。第14章是C++标准库,学习C++编程中常用的工具类与算法组件,章节最后也提供了一些算法练习题,需要用到标准库的一些组件类。第15章讲解C++新标准的一些实用的知识点,该部分知识在实际项目中会用的比较多,也是不太好理解的部分。第16章介绍文件操作,先介绍文件操作的一些基本函数,然后介绍json, xml文件的操作方法。第17章是多线程,介绍C++ 11多线程、线程池的用法。第18章介绍C++开发的相关领域,是很重要的章节,也是以后工作的参考。第19章课程总结,以及后续学习指导。
1、这是一个C/C++新手基础教程,合适完全不懂程序的新手入坑,半生不熟的程序入坑,其他语言的程序学C++。2、这是一个C++基础系列教程,本季是作为基础教程的第一集,主要为学习C语言,为学好C++打好坚实的基础,C++包含了C部分,要学好C++,学好C语言是必然的趋势。3、C++入行系列教程是一个由浅入深的一个过程,第一第二集主要学习C语言和C++,后面三集主要教大家如何用C++去写封装一些商业级案例,。第三集主要学SOCKET编程,了解熟悉socket编程。第四集主要学用C++自定义数据库,纯C++编写 第五集主要学习数据结构,学习C++的各个标准模板库。大家如有兴趣可以学习已经制作完毕的C++游戏服务器和Mysql数据库教程。4、C++入行系列教程不单单是讲解语法知识,还有另外讲解C/C++内存,以及内存优化,工作中经常用到的经验,以及避免一些坑。5、本季教程主要内容是讲解编程语言,计算机组成原理,开发环境,C语言基础语法。普及一些基础知识,并且结合工作经验讲解一些案列。教程后面会安排一些工作任务给学员。具体内容看教程课题大纲6、不保证每个人都学的会,良心之作,不喜勿买。7、教程会结合本人20年工作经验讲解工作经常用到的地方,以及新手入职面试需要注意的地方。打好基础学好C++走遍天下都不怕,相信自己,你行的。8、每一集都是单独的,需要单独购买噢,亲,请看清楚,C++系列每一集 并不是必须购买的。新手朋友第一第二集是必须学购买的哈,千万记得。切记切记切记

64,682

社区成员

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

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