内存管理3
让编程改变世界
Change the world by program
可丢弃的内存块
分配可移动内存块的时候需要使用 GMEM_MOVEABLE 标志,如果同时配合使用 GMEM_DI SCARDABLE 标志的话,这样生成的内存块是可丢弃的内存块。 表示当Windows急需内存使用的时候,可以将它从物理内存中丢弃,可丢弃的内存块首先必须是可移动的内存块。函数调用如下:
invoke GlobalAlloc, GHND or GMEM_DISCARDABLE, dwBytes .if eaxmov hMemory, eax
.endif 当用GlobalLock锁定内存的时候如果返回NULL指针,表示内存已经被Windows丢弃了。 当然其中的数据也丢失了,程序需要重新生成数据。 另外需要注意的是当内存块被丢弃的时候,内存句柄还是有效的,如果程序还要使用这个句柄,那么可以对它使用GlobalReAlloc函数来重新分配内存。 当可丢弃内存块的锁定计数为0时,程序也可以使用GlobalDiscard函数主动将它丢弃,这和Windows将它丢弃的效果是一样的:invoke GlobalDiscard, hMemory
使用内存函数时有两个地方需要特别注意
第一个需要注意的地方是:
NULL指针的检测——GlobalAlloc函数和GlobalLock函数都可以返回内存指针,在使用指针前一定要检测它的有效性。 如果使用了函数执行失败而返回的NULL指针来访问数据,会导致程序越权访问不该访问的地方,从而被Windows毫不留情地终止掉。 这就是例子代码中总是有个if语句来判断eax是否为NULL的原因。第二个需要注意的地方是:
注意访问越界问题,越界操作也会引起越权访问,千万不要到超出内存块长度的地方去访问。 例如,使用lstrcpy之类的函数处理字符串之前,先用lstrlen检测字符串长度是一个好习惯。 补充:lstrcpy函数事实上是很多溢出漏洞的根源,该函数作用是复制一个字符串到缓冲区。LPTSTR lstrcpy(LPTSTR lpString1, LPCTSTR lpString2);