VirtualAlloc函数使用总结

如果我们的程序需要动态内存的话,则迟早会调用Win32函数VirtualAlloc。但是程序也可以不调用VirtualAlloc,而是直接调用Windows堆函数或者CRT堆函数。不过,知道VirtualAlloc如何工作,可以帮助我们更好地理解这些调用函数。

    首先,必须知道保留(Reserved)内存和占用(Committed)内存的含义。当内存放保留时,一段连续虚拟地址空间被留出。例如,假如我们的程序要使用5 -MB内存块(称为区域),但并不是要马上全部使用,则我们可以调用VirtualAlloc函数,使用MEM_RESERVE分配类型参数。Windows会以64 KB为边界计算该区域的起始地址,并防止进程在同一个范围内为其他内存保留。我们可以指定区域的起始地址,但更常见的是让Windows为区域分配地址。此时除了地址分配外,其他什么也没发生。没有RAM被分配,也没有交换文件空间被保留出来。

    当我们对内存的需求更迫切时,我们可以再次调用函数VirtualAlloc来占用被保留的内存,调用时使用MEM_COMMIT分配类型参数。现在,区域的起始和结束地址都被计算到4KB边界,对应的交换文件页和所要求的页表被留出来。内存块可以被指定为只读或者可读写。然而,仍然没有RAM被分配;只有当程序访问这部分内存时RAM内存才会被真正分配。如果在此之前内存没有被保留,那就不会有问题;如果在此之前内存被占用了的话,也不会有问题。所以原则是,在使用内存之前一定要先占用。

我们可以调用VirtualFree函数“收回”(decommit)占用的内存,使指定的页回到保留的状态。VirtualFree也能够释放保留的内存区域,但我们必须指定其基地址,这个基地址是在前面调用VirtualAlloc保留内存时获得的。

 

什么时候才要用到VirtualAlloc

在没有C运行库可用的时候,要用VirtualAlloc来申请内存。另外,VirtualAlloc还可对申请的内存有许多的控制。

1、可以保留地址空间但不是及分配内存,在需要的时候再分配;

2、可以声明分配的内存不使用分页;

3、可以指定内存在尽可能高的地址上分配;

4、指定内存的读、写、执行属性和内存保护;

5、禁止所分配内存被高速缓存。

我的理解是在 malloc,new的内部实际上还是调用了virtualalloc,virtualalloc是可以自己控制页面的保留,提交,释放的实际的。实际上我们申请的内存没有使用的时候,都是被放在内存页面中,在使用的时候才会被切换到真正的物理存储器里。对于c++程序员来说 一般情况使用malloc,new就好了,除非一开始就想给自己保留一大片空间。

转载于:https://www.cnblogs.com/davidshi/p/3386710.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您想在静态函数使用类的成员,可以将类的实例作为参数传递给静态函数。以下是一个示例代码: ```cpp #include <iostream> #include <Windows.h> class CallbackClass { public: int memberVariable; static void StaticCallback(CallbackClass* instance, int value) { // 使用类的成员 std::cout << "Member variable: " << instance->memberVariable << std::endl; std::cout << "Callback value: " << value << std::endl; } }; int main() { // 分配可执行的内存块 LPVOID executableMemory = VirtualAlloc(NULL, sizeof(CallbackClass), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (executableMemory == NULL) { std::cerr << "Failed to allocate executable memory!" << std::endl; return -1; } // 创建一个类对象并设置成员变量 CallbackClass instance; instance.memberVariable = 42; // 创建一个函数指针指向静态回调函数 typedef void (*CallbackFunc)(CallbackClass*, int); CallbackFunc thunk = CallbackClass::StaticCallback; // 调用静态回调函数 int value = 10; thunk(&instance, value); // 释放内存 VirtualFree(executableMemory, 0, MEM_RELEASE); return 0; } ``` 在这个示例中,我们定义了一个包含静态回调函数 `StaticCallback` 和成员变量 `memberVariable` 的 `CallbackClass` 类。在静态回调函数中,我们通过传递类的实例指针和值参数来访问类的成员变量。 然后,我们使用 `VirtualAlloc` 函数在内存中分配了一块可执行的内存块。我们将静态回调函数的指针保存在一个函数指针 `thunk` 中。 接下来,我们创建一个类对象 `instance` 并设置成员变量的值。 最后,我们通过调用函数指针来执行静态回调函数,并传递类对象的地址和值参数。 这个示例代码演示了如何使用类Thunk技术和VirtualAlloc函数来创建可执行代码的内存块,并在静态函数中访问类的成员变量。请注意,在实际应用中,您可能需要考虑更复杂的技术和安全性问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值