如何从函数中转移一些堆内存的所有权?

安德鲁·瓦格纳

我试图编写一个函数,将命令行实用程序(image-magick)的标准输出加载到结构的成员中。我认为由于图像可以是MB,所以我最好避免复制。

/// An image data container used internally.
/// Images are 8-bit single channel for now.
pub struct Image<'a> {
    /// Width of the image in pixels.
    pub width: u32,
    /// Height of the image in pixels.
    pub height: u32,
    /// The buffer containing the image data, as a slice.
    pub pixels: &'a [u8],
}

// Load a file by first using imageMagick to convert it to a .pgm file.
fn load_using_magick<'a>(path: Path) -> Image<'a> {
    use std::io::Command;

    let output:IoResult<ProcessOutput> = Command::new("convert")
        .arg("-format pgm")
        .arg("-depth 8")
        .arg(path)
        .arg("-")
        .output();
    let output_unwrapped:ProcessOutput = match output {
        Ok(o) => o,
        Err(e) => panic!("Unable to run ImageMagick's convert tool in a separate process! convert returned: {}", e),
    };

    let bytes: &[u8] = match output_unwrapped.status.success() {
        false => panic!("signal or wrong error code from sub-process?"),
        true => output_unwrapped.output.as_slice(),
    };
    // Note, width and height will eventually get parsed out of "bytes"
    // and the returned Imaeg.pixels will point to a slice of the (already)
    // heap allocated memory.  I just need to figure out ownership first...
    Image{width:10,height:10,pixels:bytes}

}

当标准库std :: io :: Process :: Command :: output()被调用时,我想保留的一大堆内存是由标准库(或内核?)分配的。

借阅检查器编译失败:

src/loaders.rs:41:17: 41:40 error: `output_unwrapped.output` does not live long enough
src/loaders.rs:41         true => output_unwrapped.output.as_slice(),
                                  ^~~~~~~~~~~~~~~~~~~~~~~
src/loaders.rs:21:51: 48:2 note: reference must be valid for the lifetime 'a as defined on the block at 21:50...
src/loaders.rs:21 fn load_using_magick<'a>(path: Path) -> Image<'a> {
src/loaders.rs:22     use std::io::Command;
src/loaders.rs:23 
src/loaders.rs:24     let output:IoResult<ProcessOutput> = Command::new("convert")
src/loaders.rs:25         .arg("-format pgm")
src/loaders.rs:26         .arg("-depth 8")
                  ...
src/loaders.rs:21:51: 48:2 note: ...but borrowed value is only valid for the block at 21:50
src/loaders.rs:21 fn load_using_magick<'a>(path: Path) -> Image<'a> {
src/loaders.rs:22     use std::io::Command;
src/loaders.rs:23 
src/loaders.rs:24     let output:IoResult<ProcessOutput> = Command::new("convert")
src/loaders.rs:25         .arg("-format pgm")
src/loaders.rs:26         .arg("-depth 8")

这对我来说很有意义;我试图保留的所有数据块都超出了范围,在我按值返回的结构中留下了一个悬空指针。那么,在返回该存储区之前,我该如何将其所有权真正转移到我的结构上呢?

我已经阅读了Rust生时手册

用户395760

您的签名声称,无论呼叫者希望的生存时间如何,您都可以返回Image<'that_lifetime>实际上,您声称要返回Image<'static>,其中包含一个&'static [u8],即指向字节片的指针,该字节片在程序执行的整个过程中都有效。显然,ProcessOutput您实际从中获取字节片的起始时间并不长。

该存储器区域的所有权属于output_unwrapped,更具体地output_unwrapped.output(一个Vec<u8>)。您需要保留这两个中的一个。最简单的选择是将所有权授予Image:创建pixels一个Vec<u8>,然后移出output_unwrapped当然,这会对所有代码处理产生持久影响Image,因此这是一个设计问题它使意识为自己内容的图像?借款不足是否会给任何预期的使用案例带来问题?(如果您无法回答这些问题,尽管您可能只能在几周后才能找到答案,但是您可以随时尝试一下。)

一种选择是对所有权进行抽象,即允许向量和切片。通过std::borrow::Cow<[u8]>类型,甚至在标准库中也支持您只需要确定是否值得额外的麻烦,尤其是由于pixels某种原因(可能不是一个好人?)是公开的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

.Xauthority的所有权转移到根

来自分类Dev

转移Splint中的存储所有权

来自分类Dev

RAII是否支持资源所有权转移?

来自分类Dev

RAII是否支持资源所有权转移?

来自分类Dev

.Xauthority的所有权转移到根

来自分类Dev

转移Splint中的存储所有权

来自分类Dev

复制构造函数以转移unique_ptr的所有权

来自分类Dev

const正确的指针向量访问器,而无需在抽象接口中转移所有权

来自分类Dev

如何在unique_ptrs之间转移所有权

来自分类Dev

Google云端硬盘:如何使用Python SDK转移所有权?

来自分类Dev

结合使用面向对象设计和Ruby,如何显示所有权转移?

来自分类Dev

Google云端硬盘:如何使用Python SDK转移所有权?

来自分类Dev

如何实现用于模型“所有权转移”的数据结构

来自分类Dev

如何在发行版之间转移文件的所有权?

来自分类Dev

如何通过 Create/Get 组合转移 Core Foundation 所有权?

来自分类Dev

CUBLAS中的异步和内存所有权

来自分类Dev

更改共享内存的所有权

来自分类Dev

C ++析构函数和所有权

来自分类Dev

将Google Doc附件的所有权转移到另一个帐户?

来自分类Dev

NSArray如何获得C ++对象的所有权

来自分类Dev

如何更改 bintray 包所有权

来自分类Dev

转移IDisposable对象的所有权和构建器设计模式

来自分类Dev

std :: unique_ptr转移const对象的所有权

来自分类Dev

在iTunesConnect中所有权转移后将继续推送通知

来自分类Dev

转移boost :: asio :: socket堆栈变量的所有权

来自分类Dev

将所有权从std :: vector转移到std :: shared_ptr

来自分类Dev

tolua ++:将指针所有权转移到lua gc

来自分类Dev

使用门户网站进行Firebase应用转移所有权

来自分类Dev

Google云端硬盘API-从服务帐户转移所有权

Related 相关文章

  1. 1

    .Xauthority的所有权转移到根

  2. 2

    转移Splint中的存储所有权

  3. 3

    RAII是否支持资源所有权转移?

  4. 4

    RAII是否支持资源所有权转移?

  5. 5

    .Xauthority的所有权转移到根

  6. 6

    转移Splint中的存储所有权

  7. 7

    复制构造函数以转移unique_ptr的所有权

  8. 8

    const正确的指针向量访问器,而无需在抽象接口中转移所有权

  9. 9

    如何在unique_ptrs之间转移所有权

  10. 10

    Google云端硬盘:如何使用Python SDK转移所有权?

  11. 11

    结合使用面向对象设计和Ruby,如何显示所有权转移?

  12. 12

    Google云端硬盘:如何使用Python SDK转移所有权?

  13. 13

    如何实现用于模型“所有权转移”的数据结构

  14. 14

    如何在发行版之间转移文件的所有权?

  15. 15

    如何通过 Create/Get 组合转移 Core Foundation 所有权?

  16. 16

    CUBLAS中的异步和内存所有权

  17. 17

    更改共享内存的所有权

  18. 18

    C ++析构函数和所有权

  19. 19

    将Google Doc附件的所有权转移到另一个帐户?

  20. 20

    NSArray如何获得C ++对象的所有权

  21. 21

    如何更改 bintray 包所有权

  22. 22

    转移IDisposable对象的所有权和构建器设计模式

  23. 23

    std :: unique_ptr转移const对象的所有权

  24. 24

    在iTunesConnect中所有权转移后将继续推送通知

  25. 25

    转移boost :: asio :: socket堆栈变量的所有权

  26. 26

    将所有权从std :: vector转移到std :: shared_ptr

  27. 27

    tolua ++:将指针所有权转移到lua gc

  28. 28

    使用门户网站进行Firebase应用转移所有权

  29. 29

    Google云端硬盘API-从服务帐户转移所有权

热门标签

归档