< 返回版块

Louys·Miaoa 豆沙饼 发表于 2022-08-30 22:48

Tags:rust in action

在Rust in Action书中 发现的一段代码, 在Window 跑会报错 error: process didn't exit successfully: target\debug\rust_in_cation.exe (exit code: 0xc0000374, STATUS_HEAP_CORRUPTION) 请问有人知道怎么破吗?

use std::borrow::Cow;
use std::ffi::CStr;
use std::os::raw::c_char;

static B: [u8; 10] = [99, 97, 114, 114, 121, 116, 111, 119, 101, 108];
static C: [u8; 11] = [116, 104, 97, 110, 107, 115, 102, 105, 115, 104, 0];

fn main() {
    let a = 42;
    let b: String;
    let c: Cow<str>;
    unsafe {
        let b_ptr = &B as *const u8 as *mut u8;
        b = String::from_raw_parts(b_ptr, 10, 10);
        let c_ptr = &C as *const u8 as *const c_char;
        c = CStr::from_ptr(c_ptr).to_string_lossy();
    }
    println!("a: {}, b: {}, c: {}", a, b, c);
}

Ext Link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=use%20std%3A%3Aborrow%3A%3ACow%3B%0D%0Ause%20std%3A%3Affi%3A%3ACStr%3B%0D%0Ause%20std%3A%3Aos%3A%3Araw%3A%3Ac_char%3B%0D%0A%0D%0Astatic%20B%3A%20%5Bu8%3B%2010%5D%20%3D%20%5B99%2C%2097%2C%20114%2C%20114%2C%20121%2C%20116%2C%20111%2C%20119%2C%20101%2C%20108%5D%3B%0D%0Astatic%20C%3A%20%5Bu8%3B%2011%5D%20%3D%20%5B116%2C%20104%2C%2097%2C%20110%2C%20107%2C%20115%2C%20102%2C%20105%2C%20115%2C%20104%2C%200%5D%3B%0D%0A%0D%0Afn%20main()%20%7B%0D%0A%20%20%20%20let%20a%20%3D%2042%3B%0D%0A%20%20%20%20let%20b%3A%20String%3B%0D%0A%20%20%20%20let%20c%3A%20Cow%3Cstr%3E%3B%0D%0A%20%20%20%20unsafe%20%7B%0D%0A%20%20%20%20%20%20%20%20let%20b_ptr%20%3D%20%26B%20as%20*const%20u8%20as%20*mut%20u8%3B%0D%0A%20%20%20%20%20%20%20%20b%20%3D%20String%3A%3Afrom_raw_parts(b_ptr%2C%2010%2C%2010)%3B%0D%0A%20%20%20%20%20%20%20%20let%20c_ptr%20%3D%20%26C%20as%20*const%20u8%20as%20*const%20c_char%3B%0D%0A%20%20%20%20%20%20%20%20c%20%3D%20CStr%3A%3Afrom_ptr(c_ptr).to_string_lossy()%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20println!(%22a%3A%20%7B%7D%2C%20b%3A%20%7B%7D%2C%20c%3A%20%7B%7D%22%2C%20a%2C%20b%2C%20c)%3B%0D%0A%7D

评论区

写评论
作者 Louys·Miaoa 豆沙饼 2022-08-31 17:03

感谢大哥慷慨回答,非常感谢.

--
👇
Aya0wind: String获得的内存必须是从堆上申请,或者你用mem::forget来让其不要drop,否则String生命周期结束时会去释放自己的内存,而你的内存是一个全局变量数组,那尝试释放它自然会出错。

github.com/shanliu/lsys 2022-08-31 14:32

正解

use std::borrow::Cow;
use std::ffi::CStr;
use std::mem;

use std::os::raw::c_char;

static B: [u8; 10] = [99, 97, 114, 114, 121, 116, 111, 119, 101, 108];
static C: [u8; 11] = [116, 104, 97, 110, 107, 115, 102, 105, 115, 104, 0];

fn main() {
   let a = 42;
    let b: String;
    let c: Cow<str>;
    unsafe {
        let b_ptr = &B as *const u8 as *mut u8;
        let k = String::from_raw_parts(b_ptr, 10, 10);
        b=k.clone();
        mem::forget(k);
        let c_ptr = &C as *const u8 as *const c_char;
        c = CStr::from_ptr(c_ptr).to_string_lossy();
    }
    println!("a: {}, b: {}, c: {}", a, b, c);
}

--
👇
Aya0wind: String获得的内存必须是从堆上申请,或者你用mem::forget来让其不要drop,否则String生命周期结束时会去释放自己的内存,而你的内存是一个全局变量数组,那尝试释放它自然会出错。

Aya0wind 2022-08-31 09:06

String获得的内存必须是从堆上申请,或者你用mem::forget来让其不要drop,否则String生命周期结束时会去释放自己的内存,而你的内存是一个全局变量数组,那尝试释放它自然会出错。

linqingyao 2022-08-31 08:38

这不是windows的问题,是代码本身就存在 ub 行为,你可以通过miri检查看到

1 共 4 条评论, 1 页