我通过Rust的FFI调用LLVM API.LLVMPrintModuleToString 使用strdup创建一个字符串.但是,当我将指针包装在一个中时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);
}
Run Code Online (Sandbox Code Playgroud)
Valgrind错误:
==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
Run Code Online (Sandbox Code Playgroud)
为什么是这样?*char从C API 处理a的正确方法是什么?
Fra*_*gné 14
根据函数的文档:
使用LLVMDisposeMessage释放字符串.
在一般情况下,如果在一个分配内存的库中调用一个函数,你应该在该库中调用另一个释放内存的函数; 这通常应记录为函数合同的一部分.
如果函数的文档告诉您使用free,那么如果您的应用程序没有与free库的相应malloc链接(例如,您的应用程序链接到msvcr120,但库链接到msvcr100),则会出现问题.这就是为什么好的库提供了一种解除分配给你的资源的方法的原因.
Rust中的默认内存分配器不是C malloc,而是另一个名为jemalloc的分配器.CString假设字符串是使用Rust的内存分配器分配的,所以当CString析构函数运行时,它会运行jemalloc free(你可以从je_调用堆栈中的-prefixed函数告诉),但它失败了,因为字符串没有用jemalloc分配malloc.
| 归档时间: |
|
| 查看次数: |
828 次 |
| 最近记录: |