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/zh-tw/n/244634.html