【问题标题】:How to put a value in memory allocated by VirtualAlloc in c++?如何在 C++ 中将值放入由 VirtualAlloc 分配的内存中?
【发布时间】:2019-04-30 22:14:26
【问题描述】:

我正在尝试学习如何使用 VirtualAlloc 和 VirtualFree 函数。

我已经阅读了 msdn 关于 VirtualAllocVirtualFree 的参考资料,并了解了如何使用它们(至少在基本层面上)。

问题是我找不到如何将值放入分配的内存中。

我尝试编写一个简单的 C++ 应用程序:
1. 使用 VirtualAlloc 预留 3000 字节内存。
2. 提交保留的内存。
3. 将 char 类型的值放入提交的内存中。
4. 使用 VirtualFree 释放内存。

#include<windows.h>

int main() {

 LPVOID ptr = VirtualAlloc(NULL,3000,MEM_RESERVE,PAGE_READWRITE); //reserving memory

 ptr = VirtualAlloc(ptr,3000,MEM_COMMIT,PAGE_READWRITE); //commiting memory

    int i;
    for(i=0; i<3000; i++) {
       ptr[i]= 'a';         //failed attempt to fill the allocated memory with 'a'
    }

 VirtualFree(ptr, 0, MEM_RELEASE); //releasing memory

return 0;
}

当然这给出了:

[Warning] pointer of type 'void *' used in arithmetic [-Wpointer-arith]. 
[Error] 'LPVOID {aka void*}' is not a pointer-to-object type.

所以我的问题是如何正确地将值放入 C++ 中 VirtualAlloc 分配的内存中?

我还找到了 this 示例,但它没有编译,我无法让它工作。

【问题讨论】:

  • char* char_ptr = static_cast&lt;char*&gt;(ptr); char_ptr[i] = 'a'; 或者,对于您的具体示例,memset(ptr, 'a', 3000);
  • virtualalloc 和 winapi 这里完全没有关系。
  • 很难相信您链接到的代码无法编译。忽略返回值总是一个非常糟糕的主意。不要忽视错误检查。为什么要在不同的步骤中保留和提交?为什么不使用标准库分配器。
  • @David Heffernan 你说得对当它们分开时和它们在一起时都是一样的,所以为了容易区分它们,我分开使用它们。链接中的代码在 __try 和 __except ( PageFaultExceptionFilter( GetExceptionCode() ) )上给出了错误,当我将它们注释掉时,代码编译并运行,但是当它即将写入内存时它只是冻结。
  • 我没有使用标准库分配器,因为我想要更直接地控制内存,例如能够拥有大的连续指针空间并分配-释放部分而不影响(我的这里主要关注的是碎片)其余内存(例如堆)。

标签: c++ winapi memory-management virtualalloc


【解决方案1】:

@Igor Tandetnik 的回复有效

#include<windows.h>

int main() {
 LPVOID ptr = VirtualAlloc(NULL,3000,MEM_RESERVE,PAGE_READWRITE); //reserving memory
 ptr = VirtualAlloc(ptr,3000,MEM_COMMIT,PAGE_READWRITE); //commiting memory
 memset(ptr, 'a', 3000);
 VirtualFree(ptr, 0, MEM_RELEASE); //releasing memory
return 0;
}

感谢您的回复。

[编辑] 还尝试转换为 char* 并且它也有效。
再次感谢。

#include<windows.h>
int main() {
 int i;
 LPVOID ptr = VirtualAlloc(NULL,3000,MEM_RESERVE,PAGE_READWRITE); //reserving memory
ptr = VirtualAlloc(ptr,3000,MEM_COMMIT,PAGE_READWRITE); //commiting memory  
char* char_ptr = static_cast<char*>(ptr);

for(i=0;i<3000;i++){
    char_ptr[i] = 'a';  
} 

VirtualFree(ptr, 0, MEM_RELEASE); //releasing memory

return 0;
}

[编辑][2]
按照@DavidHeffernan 的建议处理返回值:

#include<windows.h>  
#include<iostream>
using namespace std; 

int main() {
size_t in_num_of_bytes,i;
cout<<"Please enter the number of bytes you want to allocate:";
cin>>in_num_of_bytes;                                      

LPVOID ptr = VirtualAlloc(NULL,in_num_of_bytes,MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE); //reserving and commiting memory

if(ptr){
    char* char_ptr = static_cast<char*>(ptr);
    for(i=0;i<in_num_of_bytes;i++){ //write to memory
        char_ptr[i] = 'a';
    }

    for(i=0;i<in_num_of_bytes;i++){ //print memory contents
        cout<<char_ptr[i];
    }

    VirtualFree(ptr, 0, MEM_RELEASE); //releasing memory    
}else{
    cout<<"[ERROR]:Could not allocate "<<in_num_of_bytes<<" bytes of memory"<<endl; 
}

return 0;
} 

【讨论】:

  • @David Heffernan 是的,我确实应该检查错误,这是从这里开始的下一步,我只是尝试一点来熟悉它。谢谢你的建议。
猜你喜欢
  • 2014-05-22
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
相关资源
最近更新 更多