[内存管理(1)] 分配和释放堆内存[TZZ]

 时间:2024-10-21 10:21:04

大家好!今天我给大家介绍一下“通过WindowsAPI函数,在调用进程的堆上分配和释放内存的方法”。微软的内存管理服务,为我们提供了一系列的进程堆管理函数。通过这些API函数,我们可以实现自己的内存管理功能,进而开发出效率更高的应用程序。如果您觉得这篇教程有帮助,请为我投上宝贵的一票(顺便求个关注),谢谢!

工具/原料

已安装VisualStudio2017(或以上版本);

已安装VS2017中的帮助文档(ViewHelper);

方法/步骤

1、打开VS2017,新建一个命名为“MemoryMgtDemo1”的“Windows控制台应用程序”项目;

2、在打开的“MemoryMgtDemo1.cpp”文件中,包含Windows.h头文竭惮蚕斗件,然后添加“获取当前进程默鹚剖蛲蛋认堆句柄”的测试代码。代码编写完毕后,调试运行程序。在弹出的控制台窗口中,可以见到“获取应用程序默认堆成功”的字样,表示GetProcessHeap函数调用成功。每个进程都有一个默认的堆内存(对应的是物理内存,并非虚拟内存中的堆内存),对于32位程序而言,其最大大小只能到4GB,超过4GB的内存将无法寻址(一维数组地址的最大值只能到unsignedlong(-1));

[内存管理(1)] 分配和释放堆内存[TZZ]

[内存管理(1)] 分配和释放堆内存[TZZ]

3、结束控制台程序,返回到main函数中。继欹爸葛端续添加“从默认堆上分配一块内存”的测试程序,然后调试运行程序,在弹出的控制台窗口中,可以见到分配内存成功的输出信息。在这份测试代码中,通过HeapA造婷用痃lloc函数从默认堆内存上分配了一块128字节的内存,然后判断该函数是否调用成功。HeapAlloc函数的第2个参数,可以设定堆内存的访问方式(默认是同步访问,加HEAP_NO_SERIALIZE则为非同步)、是否将分配的内存清0(HEAP_ZERO_MEMORY)以及是否在内存不够是抛系统异常(HEAP_GENERATE_EXCEPTIONS);

[内存管理(1)] 分配和释放堆内存[TZZ]

[内存管理(1)] 分配和释放堆内存[TZZ]

4、结束控制台程序,返回到main函数中。继续添加“获取buffer1字节大小”的测试程序,然后调试运行。在弹出的控制台窗口中,可以见到获取到的buffer1大小与分配的大小一致。在调用HeapSize时,必须保证第1个参数为堆内存句柄,第3个参数为从堆内存上分配的内存块指针;

[内存管理(1)] 分配和释放堆内存[TZZ]

[内存管理(1)] 分配和释放堆内存[TZZ]

5、结束控制台程序,返回到main函数中。继续添加“输出buffer1中所有字节”的测试代码。这份代码中,采用for循环遍历buffer1中的所有字节内存,每输出8个字节则额外输出一个回车,切换到下一行中继续输出。代码编写完毕后,调试运行程序。在弹出的控制台窗口中,可以见到打印出的buffer1的内容,其中存放的值均为内存中的残留数据;

[内存管理(1)] 分配和释放堆内存[TZZ]

[内存管理(1)] 分配和释放堆内存[TZZ]

6、结束控制台程序,返回到“MemoryMgtDemo1.cpp”文件中。在main函数之上,新增一个“tx_print_heap_memory”函数,专门用于以每行8个字节输出内存中的数据内容(多增加一个参数,则可以指定每行显示的字节数);

[内存管理(1)] 分配和释放堆内存[TZZ]

7、tx_print_heap_memory函数编写完毕后,继续向main函数中增加“从默认堆上分配内存块并将内容清0,然后将内容输出”的测试代码。使用HeapAlloc分配内存时,只要将第2个参数中增加HEAP_ZERO_MEMORY标记即可。代码编写完毕后,调试运行程序。在弹出的控制台窗口中,你会发现新分配的buffer2的内容已经被全部清0了;

[内存管理(1)] 分配和释放堆内存[TZZ]

[内存管理(1)] 分配和释放堆内存[TZZ]

8、结束控制台程序,返回到main函数中。这次试试通过HeapAlloc分配一个最大内存的测试程序。由于之前已经分配了2个128字节的内存,此时再分配最大空间,应该会妥妥的失败。测试代码编写完毕后,调试运行程序。在弹出的控制台窗口中,可以见到buffer3分配空间失败的打印信息;

[内存管理(1)] 分配和释放堆内存[TZZ]

[内存管理(1)] 分配和释放堆内存[TZZ]

9、结束控制台程序,返回到main函数中。继欹爸葛端续添加“让HeapAlloc分配空间失败抛系统异常”的测试代码。如果你跟我一样,认为HeapAlloc抛的异常可以被try…catch捕获到,那恐怕醐肛们亲要令你失望了。测试代码编写完毕后,调试运行程序。随后,VS2017直接弹出了“未经处理的异常”提示框。由此可知,HeapAlloc函数抛出的异常类型,无法通过try...catch捕获。它属于系统级的,关于处理这种异常(比如:除0,访问非法内存等)的方法,请参考“结构化异常处理”;

[内存管理(1)] 分配和释放堆内存[TZZ]

[内存管理(1)] 分配和释放堆内存[TZZ]

10、在VS2017中停止控制台程序,返回到main函数中。将HeapAlloc抛异常的测试代码全部注释掉,然后增加通过HeapFree函数释放buffer1和buffer2的代码。编写C++程序时,凡是在堆上分配的内存,均需要手动释放,否则会造成内存泄漏(更好的习惯是使用std::shared_ptr类管理分配的堆内存空间);

[内存管理(1)] 分配和释放堆内存[TZZ]

[内存管理(1)] 分配和释放堆内存[TZZ]

11、至此,在堆上分配和释放内存的测试代码就介绍完毕了。如果您希望学到更多实用的编程知识,记得关注我哦!Enjoy!

C#里的SQL语句in的多个参数怎么用 谈一下计算机专业方面的面试 Android 安装apk包的五种方式 不良人手游藏兵谷门怎么开 QQ消息记录密码忘了怎么办
热门搜索
不知火舞 漫画 金蟾图片 刺绣图片 轿车图片 日常幻想指南漫画