You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust稳定版中如何实现类似C/C++的手动内存管理?

手动在Rust中模拟C/C++风格的内存管理(学习用)

Great question—since you’re doing this purely for learning, digging into Rust’s low-level memory primitives is a fantastic way to understand how its safety guarantees work under the hood. Let’s break this down:

首先:Rust稳定版的内存分配原语

Rust doesn’t expose direct malloc/free or new/delete equivalents in its safe API (for good reason—those are frequent sources of bugs like double-frees or dangling pointers). But for learning, you absolutely can use stable, low-level allocation APIs to replicate that behavior, plus some experimental (unstable) tools if you want to go even deeper.

核心工具:std::alloc 和 std::ptr

The stable standard library provides two key modules for this:

  • std::alloc: Handles raw memory allocation/deallocation (like malloc/free).
  • std::ptr: Provides functions to safely (well, as safely as possible in unsafe code) interact with raw pointers—like initializing memory, reading values, or dropping objects (like the constructor/destructor part of new/delete).

示例:手动分配、初始化、使用、释放一个值

Here’s a simple example that mimics malloc + new + delete + free for an i32 (we’ll expand to more complex types too):

use std::alloc::{alloc, dealloc, Layout};
use std::ptr;

fn main() {
    // Step 1: Define the memory layout (size and alignment for our type)
    let layout = Layout::new::<i32>();

    // Step 2: Allocate raw, uninitialized memory (like malloc)
    let raw_ptr = unsafe { alloc(layout) };
    if raw_ptr.is_null() {
        panic!("Memory allocation failed—out of memory!");
    }

    // Step 3: Initialize the memory (like the constructor part of new)
    unsafe {
        // Write a value to the raw pointer (avoids reading uninitialized memory)
        ptr::write(raw_ptr as *mut i32, 42);

        // Step 4: Use the value
        let value = ptr::read(raw_ptr as *const i32);
        println!("Stored value: {}", value);

        // Step 5: Clean up (for types with Drop, run the destructor first)
        // For i32, this is unnecessary, but for a String or Vec, you'd do:
        // ptr::drop_in_place(raw_ptr as *mut String);

        // Step 6: Deallocate the raw memory (like free)
        dealloc(raw_ptr, layout);
    }
}

处理更复杂的类型(带Drop trait)

For types that have a destructor (like String, Vec, or your own structs with Drop), you need to explicitly run the destructor before deallocating memory—otherwise you’ll get memory leaks (just like forgetting to call a destructor in C++). Here’s how that looks for a String:

use std::alloc::{alloc, dealloc, Layout};
use std::ptr;

fn main() {
    let layout = Layout::new::<String>();
    let raw_ptr = unsafe { alloc(layout) };
    if raw_ptr.is_null() {
        panic!("Allocation failed");
    }

    unsafe {
        // Initialize a String in the raw memory (equivalent to new String("hello"))
        ptr::write(raw_ptr as *mut String, String::from("hello"));

        let s = ptr::read(raw_ptr as *const String);
        println!("String value: {}", s);

        // Put the string back so we can drop it (since read moves the value)
        ptr::write(raw_ptr as *mut String, s);

        // Run the destructor (equivalent to delete's destructor call)
        ptr::drop_in_place(raw_ptr as *mut String);

        // Deallocate the raw memory
        dealloc(raw_ptr, layout);
    }
}

关于experimental的ptr模块API

Some more niche pointer operations are still marked as experimental (unstable) and require enabling a feature flag in your project. For example:

  • std::ptr::realloc: While the stable Allocator trait has a realloc method (via std::alloc::Global.realloc()), there’s an unstable ptr::realloc that works directly with raw pointers.
  • std::ptr::alloc/std::ptr::dealloc: Older, deprecated aliases for the alloc module’s functions.

To use unstable APIs, you’ll need to add a feature flag to your crate root:

#![feature(ptr_realloc)] // Example for the unstable realloc function

Keep in mind that unstable APIs can change between Rust versions, so they’re not recommended for production—but perfect for learning!

关于"Heap结构"的误区

You mentioned a "Heap structure"—I think you might be confusing the heap data structure (like std::collections::BinaryHeap) with the heap memory region where dynamic allocations live. For manual memory management, you don’t need the BinaryHeap collection—instead, you’ll use the allocator APIs from std::alloc to interact with the system’s heap directly.

关键提醒:所有这些都是unsafe

Every part of this code requires the unsafe keyword because you’re bypassing Rust’s safety checks. You’re responsible for:

  • Ensuring memory is initialized before reading it
  • Avoiding double-frees
  • Not using dangling pointers
  • Running destructors for types that need them

This is exactly why Rust’s safe API hides these details—manual memory management is error-prone! But for learning, it’s a great way to appreciate how Rust’s ownership system prevents these bugs automatically.

内容的提问来源于stack exchange,提问作者LppEdd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:47:47