Memory management 在运行时在堆上分配缓冲区

Memory management 在运行时在堆上分配缓冲区,memory-management,heap,rust,ownership,Memory Management,Heap,Rust,Ownership,我通过编写简单的二进制解码器来学习Rust 我正在使用带的BufferedReader读取数字,但在读取字节缓冲区时遇到问题 我想将字节数据读入运行时分配的缓冲区。 然后我想把这个缓冲区的所有权传递给一个结构。当struct不再使用时,应该释放缓冲区 除了一些Vec::with_capacity()hack之外,似乎没有办法在堆上分配运行时确定大小的数组。有没有办法用正确的Rust语义来实现这一点 我试过使用box,但它似乎是实验性的,我无法将其用于发布分支。有没有办法用正确的Rust语义来实现

我通过编写简单的二进制解码器来学习Rust

我正在使用带的
BufferedReader
读取数字,但在读取字节缓冲区时遇到问题

我想将字节数据读入运行时分配的缓冲区。 然后我想把这个缓冲区的所有权传递给一个结构。当struct不再使用时,应该释放缓冲区

除了一些
Vec::with_capacity()
hack之外,似乎没有办法在堆上分配运行时确定大小的数组。有没有办法用正确的Rust语义来实现这一点

我试过使用
box
,但它似乎是实验性的,我无法将其用于发布分支。有没有办法用正确的Rust语义来实现这一点

这一点已在,特别是“第”节中介绍

使用:

fn main(){
让我们回答:Box=Box::new(42);
} 
另见:

我试过使用
box
,但它似乎是实验性的,我无法将其用于发布分支。有没有办法用正确的Rust语义来实现这一点

这一点已在,特别是“第”节中介绍

使用:

fn main(){
让我们回答:Box=Box::new(42);
} 
另见:


    • Rust是一种低级语言;因此,您可以分配原始内存,然后自己用对象填充它。当然,它需要
      不安全的
      代码,就像所有摆弄原始内存的行为一样

      这是:


      当然,在真正的代码中,我只会使用
      Vec
      为我安全地管理内存。更简单

      Rust是一种低级语言;因此,您可以分配原始内存,然后自己用对象填充它。当然,它需要
      不安全的
      代码,就像所有摆弄原始内存的行为一样

      这是:


      当然,在真正的代码中,我只会使用
      Vec
      为我安全地管理内存。更简单

      这将创建一个预分配的可变500MB字节的零缓冲区,该缓冲区存储在堆上,不需要不安全的数据:

      //正确的

      让mut buffer=vec![0_u8;536870912];
      
      请注意,下面的代码不是一个好主意,很可能会导致堆栈溢出,因为缓冲区是在装箱并移动到堆之前在堆栈上创建的

      //不正确-使用了堆栈

      let mut bytes:Box=Box::new([0_u8;536870912])
      
      //不正确-速度慢

      let mut bytes=Vec::具有_容量(536870912);
      对于0..bytes.capacity()中的uu{
      字节。推送(0_u8);
      }
      
      这将创建一个预分配的可变500MB字节零缓冲区,该缓冲区存储在堆上,不需要不安全的数据:

      //正确的

      让mut buffer=vec![0_u8;536870912];
      
      请注意,下面的代码不是一个好主意,很可能会导致堆栈溢出,因为缓冲区是在装箱并移动到堆之前在堆栈上创建的

      //不正确-使用了堆栈

      let mut bytes:Box=Box::new([0_u8;536870912])
      
      //不正确-速度慢

      let mut bytes=Vec::具有_容量(536870912);
      对于0..bytes.capacity()中的uu{
      字节。推送(0_u8);
      }
      
      您的问题似乎更接近“如何在稳定代码中使用
      框的功能”。也许你应该更新你的标题。只是“语义学”的一点:
      box
      是正确的锈迹,现在还不是稳定的锈迹:)你的问题似乎更接近于“如何在稳定的代码中使用
      box
      的功能”。也许你应该更新你的标题。只是“语义学”的一点:
      box
      是正确的锈迹,现在还不是稳定的锈迹:)是的,
      box::new
      在堆上创建变量。但据我所知,调用
      Box::new
      会在堆栈上创建变量,函数调用会将其复制到堆中<代码>框
      语法应该在堆AFAIK上创建。这可能是个问题,因为我想创建512 KB缓冲区。@semtexzv您能指出一些文档或反汇编来证实这一点吗?Rust(由LLVM提供)背后的优化器非常强大。
      let mut xx=Box::new([0u8;5000000])导致堆栈溢出。它应该分配5兆的数据。但我可能理解错了。@semtexzv如果您不这样做,它会启用优化。问题不是使用
      Box::new
      问题是在运行时直接在堆上分配数组。是的,
      Box::new
      会在堆上创建变量。但据我所知,调用
      Box::new
      会在堆栈上创建变量,函数调用会将其复制到堆中<代码>框
      语法应该在堆AFAIK上创建。这可能是个问题,因为我想创建512 KB缓冲区。@semtexzv您能指出一些文档或反汇编来证实这一点吗?Rust(由LLVM提供)背后的优化器非常强大。
      let mut xx=Box::new([0u8;5000000])导致堆栈溢出。它应该分配5兆的数据。但我可能理解错了。@semtexzv如果你,这可以实现优化。问题不是使用
      Box::new
      问题是在运行时直接在堆上分配数组。自己用对象填充数组-值得一提的是零大小的类型和析构函数以及解释为什么使用
      Vec
      更好的所有其他复杂性吗?任何人都可以使用
      作为*mut i32
      而不是
      transmute
      ?并且可能使用
      mem::size_of
      而不是硬编码
      4
      ?出于我自己的好奇,为什么要将内存与4K块对齐+“只需使用
      Vec
      ”^^ 1。@Shepmaster:我在列举大量潜在问题时犹豫不决,但我担心这听起来像是漫无边际的……有一天,你可以成为像我这样的专业漫无边际的人!;-)你自己用物体填充它-它有效吗
      fn main() {
          let answer: Box<u8> = Box::new(42);
      } 
      
      use std::{
          alloc::{self, Layout},
          mem, ptr,
      };
      
      fn main() {
          unsafe {
              let layout = Layout::from_size_align(512 * 1024, 4 * 1024).expect("Invalid layout");
              let mut raw: *mut i32 = mem::transmute(alloc::alloc(layout));
      
              for i in 0..(512 * 1024 / 4) {
                  ptr::write(raw, i as i32);
                  raw = raw.offset(1)
              }
          }
      }