以下是铁 rust 代码:

use std::alloc;

fn main() {
    let name = String::from("a");
    let obj = unsafe { GcObject::allocate(name) };

    println!("{:?}", obj.object);
}

pub struct GcObject {
    object: *mut Object,
}

impl GcObject {
    pub unsafe fn allocate(object: String) -> Self {
        let layout = alloc::Layout::new::<Object>();

        // Allocate the object
        let ptr = alloc::alloc(layout) as *mut Object;

        if ptr.is_null() {
            eprintln!("Alloc error!");
            alloc::handle_alloc_error(layout);
        }

        *ptr = Object { kind: object };

        GcObject { object: ptr }
    }
}

struct Object {
    kind: String,
}

Rustc version: rustc 1.70.0 (90c541806 2023-05-31)
Platform: Fedora Linux 38

When compiled with following runs fine:
rustc main.rs -C opt_level=0

But when compiled with optimizations enabled like:
rustc main.rs -C opt_level=3
Causes a crash when run with the following message:

Illegal instruction(core dumped)

那么,有没有办法解决这个问题,或者我的代码有问题.

推荐答案

当赋值大于ptr时,您的代码会触发未定义的行为.事实上,除非某个值被标记为可能未初始化,否则Rust会假定每个值都已初始化,因此写入新值来代替旧值需要drop个旧值(在您的例子中是something,因为您的数据包含String,它有一些清理代码).

相反,您可以使用MaybeUninitptr::write来避免这种隐式释放清理.但它们都不安全.更好(更安全)的解决方案是使用Box::new分配,然后使用Box::leak泄漏指针.

仅供参考,Rust标准库中的所有unsafe个函数在其文档中都必须满足不触发UB的确切条件.由于编写不安全代码很困难,因为有lot种可能触发UB的事情是人们无法猜测的,所以明智的做法是判断每个不安全操作,并添加注释来解释为什么正确使用了该操作.

Rust相关问答推荐

go 掉包装 struct 中的泛型

使用pyo3::Types::PyIterator的无限内存使用量

获取字符串切片(&;str)上的切片([ia..ib])返回字符串

在Rust中,如果Result是Err,运行副作用(如日志(log)记录)的惯用方法是什么

如何编写一个以一个闭包为参数的函数,该函数以另一个闭包为参数?

如何修复数组中NewType导致的运行时开销

我应该将哪些文件放入我的GitHub存储库

Rust 的多态现象.AsRef与Derf

如何在不调用Collect()的情况下为新型vec实现IntoIterator?

通过RabbitMQ取消铁 rust 中长时间运行的人造丝任务的策略

为什么Deref类特征不构成?

如何在嵌套的泛型 struct 中调用泛型方法?

为什么我的trait 对象类型不匹配?

‘&T as *const T as *mut T’ 在 ‘static mut’ 项目中合适吗?

实现AsyncWrite到hyper Sender时发生生命周期错误

打印 `format_args!` 时borrow 时临时值丢失

强制特征仅在 Rust 中的给定类型大小上实现

第 7.4 章片段中如何定义 `thread_rng`

预期的整数,找到 `&{integer}`

我可以在不调用 .clone() 的情况下在类型转换期间重用 struct 字段吗?