0%

Windows核心编程 - 堆栈

最近在学习 Win32编程,所以顺便将每日所学记录下来,一方面为了巩固学习的知识,另一方面也为同样在学习Win32开发的童鞋们提供一份参考。

本系列博文均根据学习《Windows核心编程》一书总结而来;

运行环境:

  • 操作系统: Windows 10家庭版
  • 编译器:Visual Studio 2019

堆栈

线程用来分配许多较小的数据块。

进程的默认堆栈

线程的默认堆栈大小是1MB,但是系统可以扩大进程的默认堆栈。当创建程序的时候,可以使用/HEAP链接开关;

可以调用GetProcessHeap函数获取进程默认堆栈的句柄;

1
2
3
4
5
6
7
8
9
10
#include <windows.h>
#include <tchar.h>
#include <stdio.h>

int main()
{
int* p = (int*)malloc(sizeof(int));
HANDLE hProceeHeap = GetProcessHeap();
return 0;
}

创建辅助堆栈

在进程中创建辅助堆栈,放是调用HeapCreate函数:

1
2
3
HANDLE HeapCreate(DWORD flOptions, 			//flOptions用于修改如何在堆栈上执行各种操作。你可以设定 0、HEAP_NO_SERIALIZE、 HEAP_GENERATE_EXCEPTIONS或者是这两个标志的组合。
DWORD dwInitialSize, //堆的初始大小
DWORD dwMaximumSize ); //如果该参数是一个非零的值,它指定了这个堆的最大大小,单位为Bytes

HeapAlloc必须执行以下操作:

  • 遍历分配的和释放的内存块的链表
  • 寻找一个空闲内存块的地址
  • 通过将空闲内存块标记为”已分配”分配新内存块
  • 将新内存块添加给内存块链表

堆分配内存

若要从堆中分配内存块,只需要调用HeapAlloc函数

1
2
3
LPVOID HeapAlloc(HANDLE hHeap, 			//堆申请句柄
DWORD dwFlags, //H E A P _ Z E R O _ M E M O RY、 H E A P _ G E N E R AT E _ E X C E P T I O N S和H E A P _ N O _S E R I A L I Z E
DWORD dwBytes ); //分配大小

改变内存大小

当我们所有的数据存入内存的时候,再缩小内存块的大小

1
2
3
4
LPVOID HeapReAlloc(HANDLE hHeap, 
DWORD dwFlags,
LPVOID lpMem, //改变的大小
DWORD dwBytes ); //新内存块大小

获取内存的大小

1
2
3
DWORD HeapSize( HANDLE hHeap, 
DWORD dwFlags,
LPCVOID lpMem );

释放堆内存

当不在需要内存块时,可以调用HeapFree函数来释放:

1
2
3
BOOL HeapFree(HANDLE hHeap, 		//释放的句柄
DWORD dwFlags, //标志
LPVOID lpMem ); //大小

释放堆栈

1
BOOL HeapDestroy(HANDLE hHeap );		//堆栈句柄

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<windows.h>
#include<stdio.h>
#include<tchar.h>
#include<iostream>
using namespace std;
HANDLE hHeap;
int _tmain(int argc, _TCHAR* argv[]) {
SYSTEM_INFO systeminfo;
GetSystemInfo(&systeminfo);
cout << "page" << systeminfo.dwPageSize << endl;
hHeap = HeapCreate(HEAP_GENERATE_EXCEPTIONS, 1024, 4096); //这里的最大堆空间需要注意一下


if (NULL == hHeap) {
printf("HeapCreate失败\n");
return 1;
}

for (int i = 0; i < 40; i++) {
LPVOID p4 = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 1);
cout << i << endl;
}



system("pause");
return 0;
}