Win32学习笔记(19)私有内存的申请释放

1.申请内存的两种方式:

<1>通过VirtualAlloc/VirtualAllocEx(后面会介绍,两者在底层的实现相同)申请的: Private Memory

<2>通过CreateFileMapping映射的: Mapped Memory

 

这个图我们已经熟悉了,不过物理页有着Map和Private两种。Map是公有物理页,Private是私有物理页。所以物理内存只分为两种一种是自己独占物理页,一种是和别人共享物理页。

2.内存申请与释放:

LPVOID VirtualAlloc(
  [in, optional] LPVOID lpAddress,//要分配的内存区域的地址
  [in]           SIZE_T dwSize,//分配的大小
  [in]           DWORD  flAllocationType,//分配的类型 MEM_COMMIT MEM_RESERVE
  [in]           DWORD  flProtect//该内存的初识保护属性
);
LPVOID VirtualAllocEx(
  [in]           HANDLE hProcess,
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);

VirtualAlloc函数是在自己的进程里面申请内存

VirtualAllocEx函数可以指定一个进程id,就是可以在别的进程中申请

查阅文档看一下分配的类型:
我们主要用到
MEM_COMMIT:不但占用地址,还要物理内存(即占坑也需要物理页)
MEM_RESERVE:把需要的线性地址留出来,不过不需要物理内存(先把坑站着,不过不需要物理页)

下面我们尝试获取内存,示例代码:

#include"stdafx.h"
#include<stdio.h>
#include<Windows.h>
int main()
{
    LPVOID p = VirtualAlloc(
        NULL,//第一个参数我们可以指定一个地址,不过一般不需要因为我们不知道哪个地址已经被使用了,所以我们一般不用指定
        0x1000*2,//分配的大小(以字节为单位),我们一般以页为基本单位(4kb就是4096个字节),
        MEM_COMMIT,
        PAGE_READWRITE//你希望你的物理内存有什么属性(查阅官方文档),我这里是可读可写
    );
    printf("%x\n", p);//打印出占用的地址
    if (p == NULL)
    {
        printf("error");
    }
    else
    {
        printf("get");
    }
    return 0;
}

我们在调试的时候查看内存,没有分配内存的时候是这样

 

注意:这个地址是随便的,因为我不知道系统会占哪个内存,所以等打印出p后再去找

 

我们去找这个地址

 

可以看到已经分配了。

申请内存只有两种方式,一种是独占内存(如上),一种是分享物理页通过CreateFileMapping实现

下面我们再试试释放内存:使用函数VirtualFree

BOOL VirtualFree(
  [in] LPVOID lpAddress,  //指向要释放的页面区域的基址的指针。
  [in] SIZE_T dwSize,
  [in] DWORD  dwFreeType
);
介绍一下第三个参数

MEM_DECOMMIT:保留虚拟地址保留,物理页不保留
MEM_RELEASE:都不保留(使用时第二个参数填0)

示例代码如下:

#include"stdafx.h"
#include<stdio.h>
#include<Windows.h>
int main()
{
    LPVOID p = VirtualAlloc(
        NULL,//第一个参数我们可以指定一个地址,不过一般不需要因为我们不知道哪个地址已经被使用了,所以我们一般不用指定
        0x1000*2,//分配的大小(以字节为单位),我们一般以页为基本单位(4kb就是4096个字节),
        MEM_COMMIT,
        PAGE_READWRITE//你希望你的物理内存有什么属性(查阅官方文档),我这里是可读可写
    );
    printf("%x\n", p);
    if (p == NULL)
    {
        printf("error");
    }
    else
    {
        printf("get");
    }
    VirtualFree(p, 0, MEM_RELEASE);
    return 0;
}

 

释放前

 

释放后,

 

3.堆与栈

可能有疑问,我们在学c语言的时候使用的malloc不也是申请内存吗?其实malloc是从VirtualAlloc申请的内存中拿出一小块来使用。malloc是假申请,VirtualAlloc是真申请。

示例代码:

#include"stdafx.h"
#include<stdio.h>
#include<Windows.h>
int main()
{
    int x = 0x12345678;
    int* y = (int*)malloc(sizeof(int) * 128);
    printf("栈:%x \n", &x);//局部变量等叫栈内存
    printf("堆:%x \n", y);//用malloc申请的内存叫堆内存
    getchar();
    return 0;
}

其实无论是堆内存还是栈内存,我们操作系统启动时操作系统已经使用VirtualAlloc为我们申请了,就是你还没申请其实已经申请过了。

输出:

 

我们可以试一下不用malloc申请,其实不用的话操作系统也为我们申请好了(因为这个地址每次都是变的我就不尝试了)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wzprabbit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值