GlobalAlloc是Windows API中的一个函数,它可以用来在本地进程堆中分配指定大小的内存。本文将从多个方面详细讲解globalAlloc。
一、globalAlloc函数
globalAlloc作为一种内存分配函数,其主要作用是在进程堆中分配一块指定大小的内存,并返回指向分配内存的指针(或空指针)。其函数原型如下:
HGLOBAL GlobalAlloc( UINT uFlags, SIZE_T dwBytes );
其中,uFlags
可以为以下几种常量:
GMEM_FIXED
:要求内存分配成功并且分配出来的内存地址不变GMEM_MOVEABLE
:要求分配的内存空间可以移动(通过GlobalReAlloc函数)GMEM_ZEROINIT
:要求全局分配缓冲区的内部所有位都被初始化为零
而dwBytes
则代表要分配的内存大小,单位为字节(Byte)。
二、globalAlloc rust
Rust是一门功能强大的系统编程语言,同样也可以使用globalAlloc函数。具体使用步骤:
- 将以下代码复制并粘贴至项目根目录下的Cargo.toml文件:
[features] std = ["alloc_system"] [dependencies] alloc_system = { version = "0.3.2", optional = true }
- 在源文件中引入alloc库和globalAlloc:
#![feature(global_allocator)] #![global_allocator] static GLOBAL: std::alloc::System = std::alloc::System;
- 使用globalAlloc:
use std::alloc::{GlobalAlloc, Layout}; struct MyAllocator; unsafe impl GlobalAlloc for MyAllocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { GlobalAlloc::alloc(&std::alloc::System, layout) } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { GlobalAlloc::dealloc(&std::alloc::System, ptr, layout) } } #[global_allocator] static GLOBAL: MyAllocator = MyAllocator; fn main() { let n = 1024*1024; let layout = Layout::from_size_align(n, 1).unwrap(); let ptr = unsafe { GLOBAL.alloc(layout) }; if ptr.is_null() { panic!("Out of memory"); } }
三、globalAlloc和new
对于内存分配,常见的方式除了globalAlloc之外,还有使用new运算符。二者的差异在于,使用new运算符是对于某种类型的内存进行分配,而globalAlloc则是分配了若干个字节的内存。当然,也可以在globalAlloc之上进行进一步的类型转换。
struct MyStruct { x: i32, y: i32, } let my_struct = unsafe { let layout = Layout::new::(); GlobalAlloc::alloc(&SYSTEM_ALLOCATOR, layout) as *mut MyStruct }; *my_struct = MyStruct { x: 1, y: 2 };
四、globalAlloc malloc 多大
在进行内存分配时,需要指定内存大小。但是,如何决定这个内存的大小呢?这与用户的具体需求有关。如果内存大小太小,可能无法满足程序的需要;而内存太大则会造成浪费。可以通过用户提供特定数据的大小等方法进行内存大小的设定。
const NAME_SIZE: usize = 256; let layout = Layout::from_size_align(NAME_SIZE, 1).unwrap(); let name_ptr = unsafe { GlobalAlloc::alloc(&SYSTEM_ALLOCATOR, layout) };
五、globalAlloc failed
在进行内存分配时,可能会分配失败。出现分配失败的原因可能为:内存不足、内存碎片化、PC卡或存储控制器发生故障等。如果globalAlloc分配失败,则返回空指针,需要对此进行判断,如果出现空指针,需要进行相应的错误处理。
let layout = Layout::from_size_align(usize::MAX, 1).unwrap(); let ptr = unsafe { GlobalAlloc::alloc(&SYSTEM_ALLOCATOR, layout) }; if ptr.is_null() { println!("Allocation failed!"); }
六、globalAlloc的执行效率
globalAlloc效率高于C++的new或malloc函数,因为globalAlloc使用的是自己的线程安全的堆内存,而C++的new或malloc函数使用的是全局内存。
七、globalAlloc和virtualalloc区别
globalAlloc和virtualalloc都是用来分配内存的函数,但它们的使用场景不同。
globalAlloc在进程的堆中分配内存(Allocates Memory from Process’s Heap),而virtualalloc则用于访问未分配的虚拟内存(Reserves Pages of Virtual Memory),这个虚拟内存可以是每个进程的专用地址空间(无论是保留还是提交)。因此,当需要在进程的地址空间中分配内存时,请使用globalAlloc;而当需要访问未分配的虚拟内存时,请使用virtualalloc。
Code
use std::alloc::{GlobalAlloc, Layout}; struct MyAllocator; unsafe impl GlobalAlloc for MyAllocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { GlobalAlloc::alloc(&std::alloc::System, layout) } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { GlobalAlloc::dealloc(&std::alloc::System, ptr, layout) } } #[global_allocator] static GLOBAL: MyAllocator = MyAllocator; fn main() { let n = 1024*1024; let layout = Layout::from_size_align(n, 1).unwrap(); let ptr = unsafe { GLOBAL.alloc(layout) }; if ptr.is_null() { panic!("Out of memory"); } }
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/244634.html