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

为何String转*const i8再转回后数据异常?Rust FFI问题

悬垂指针导致FFI字符串转换异常的问题分析

你的代码中两次字符串转换结果不一致的核心原因是悬垂指针:

循环内创建的CString实例c_item在每次迭代结束后就会被Rust的所有权机制销毁,它持有的堆内存被释放。虽然你把c_item.as_ptr()的结果存入了container,但这个指针指向的内存击倒This_dayV循环室内雅 多个 AW soundGreat,工具�,后续访问时读取到的是随机垃圾数据。

为什么第一次循环能正常输出?

第一个循环中,println语句和c_item处于同一个代码块(循环迭代的作用域),此时c_item还未被销毁,指针指向的内存仍然有效,所以能正确解析出字符串内容。

解决办法:延长CString的生命周期

要让指针始终有效,需要保证CString实例的生命周期和container一样长。可以用一个额外的向量存储所有CString实例,避免它们被提前销毁:

use std::ffi::{CStr, CString};

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub enum MyValue {
    String(*const i8),
}

fn main() {
    let content = vec!["Hello", "world"];
    let mut container: Vec<MyValue> = vec![];
    let mut c_strings: Vec<CString> = vec![]; // 保存CString实例,延长生命周期

    // Generate data
    for item in content {
        let c_item = CString::new(item).unwrap();
        c_strings.push(c_item);
        let c_item_ref = c_strings.last().unwrap();
        container.push(MyValue::String(c_item_ref.as_ptr() as *const i8));

        let my_var = *container.last().unwrap();
        let MyValue::String(my_var_address) = my_var else {
            panic!("Error")
        };

        let real_content = unsafe { CStr::from_ptr(my_var_address) };
        println!("Before-Pointer > real_value: {:?}", real_content);
    }

    println!("====================");
    
    // Convert vector to vector pointer
    let container_ptr = container.as_ptr();
    // Get value
    for i in 0..container.len() as isize {
        let my_var_p = unsafe { *container_ptr.offset(i) };
        let MyValue::String(my_var_address_ptr) = my_var_p else {
            panic!("Error")
        };

        let real_content_ptr = unsafe { CStr::from_ptr(my_var_address_ptr) };
        println!("After-Pointer > real_value: {:?}", real_content_ptr);
    }
}

修改后,c_strings会持有所有CString实例的所有权,只要c_strings不被销毁,指针指向的内存就始终有效,两次循环都能正确输出字符串内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:22:39