如何在 Rust 中释放通过 FFI 分配的 *char?

2024-02-11

我通过 Rust 的 FFI 调用 LLVM API。LLVMPrintModuleToString 使用strdup创建字符串 http://llvm.org/docs/doxygen/html/Core_8cpp_source.html#l00205。但是,当我将指针包裹在CString,当 Rust 丢弃它时,我收到错误。

#![feature(cstr_memory)]
use std::ffi::CString;

extern crate llvm_sys as llvm;

fn main() {
    let llvm_ir_cstring;
    unsafe {
        let module = llvm::core::LLVMModuleCreateWithName(b"nop\0".as_ptr() as *const _);
        let llvm_ir_char_ptr = llvm::core::LLVMPrintModuleToString(module);
        llvm::core::LLVMDisposeModule(module);
        llvm_ir_cstring = CString::from_ptr(llvm_ir_char_ptr);
    }

    println!("llvm_ir_cstring: {:?}", llvm_ir_cstring);
}

瓦尔格林错误:

==10413== Invalid read of size 4
==10413==    at 0x4870586: pthread_mutex_lock (in /usr/lib/libpthread-2.21.so)
==10413==    by 0x17F89B: je_arena_dalloc_small (in /home/wilfred/projects/bfc/target/debug/bfc)
==10413==    by 0x178C30: je_sdallocx (in /home/wilfred/projects/bfc/target/debug/bfc)
==10413==    by 0x10FA57: heap::imp::deallocate::h1fb92d59333c497bkja (heap.rs:268)
==10413==    by 0x10F999: heap::deallocate::h5680e3fedc9e96320da (heap.rs:89)
==10413==    by 0x10F929: heap::exchange_free::h452463f962f7ec23kfa (heap.rs:131)
==10413==    by 0x10F8C5: Box$LT$$u5b$u8$u5d$$GT$::drop.1769::haf7017472635c7cf (in /home/wilfred/projects/bfc/target/debug/bfc)
==10413==    by 0x10F836: std..ffi..c_str..CString::drop.1766::h04d2b3db8d468f0c (in /home/wilfred/projects/bfc/target/debug/bfc)
==10413==    by 0x10F5FF: main::h04b7feb343e229ccgaa (in /home/wilfred/projects/bfc/target/debug/bfc)
==10413==    by 0x16DBCA: rt::unwind::try::try_fn::h2403085009213705177 (in /home/wilfred/projects/bfc/target/debug/bfc)
==10413==    by 0x16FF5A: rust_try_inner (in /home/wilfred/projects/bfc/target/debug/bfc)
==10413==    by 0x16FF33: rust_try (in /home/wilfred/projects/bfc/target/debug/bfc)
==10413==  Address 0x1d684 is not stack'd, malloc'd or (recently) free'd

为什么是这样?正确的处理方法是什么*char来自 C API?


根据函数的文档 http://llvm.org/docs/doxygen/html/group__LLVMCCoreModule.html#gad150d942dc9f49238f57cb89464c01df:

使用 LLVMDisposeMessage 释放字符串。

一般情况下,如果您调用库中分配内存的函数,则应该调用该库中另一个释放内存的函数;这通常应该记录为函数合同的一部分。

如果函数的文档告诉您使用free,那么如果您的应用程序未与free对应图书馆的malloc(例如,您的应用程序与 msvcr120 链接,但库与 msvcr100 链接)。这就是为什么好的库提供了一种方法来释放它为您分配的资源的原因。

Rust 中的默认内存分配器不是 C 的malloc,但另一个分配器称为jemalloc http://www.canonware.com/jemalloc/. CString假设字符串是用 Rust 的内存分配器分配的,所以当CString的析构函数运行,它运行 jemalloc 的free(你可以从je_- 调用堆栈中的前缀函数),但它失败,因为该字符串未使用 jemalloc 分配malloc.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Rust 中释放通过 FFI 分配的 *char? 的相关文章

随机推荐