10

Once I have allocated the array, how do I manually free it? Is pointer arithmetic possible in unsafe mode?

Like in C++:

double *A=new double[1000];
double *p=A;
int i;
for(i=0; i<1000; i++)
{
     *p=(double)i;
      p++;
}
delete[] A;

Is there any equivalent code in Rust?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 1
    The arrays sections from here (http://rustbyexample.com/primitives/array.html) might be able to help you. – hurnhu Dec 21 '15 at 15:45
  • 8
    I would point out that this is terrible C++ code (the presence of `delete` is a give-away). Idiomatic C++ would be `std::vector A; for (int i = 0; i < 1000; ++i) { A.push_back(i); }`: no explicit memory manipulation! – Matthieu M. Dec 21 '15 at 16:15

2 Answers2

19

Based on your question, I'd recommend reading the Rust Book if you haven't done so already. Idiomatic Rust will almost never involve manually freeing memory.

As for the equivalent to a dynamic array, you want a vector. Unless you're doing something unusual, you should avoid pointer arithmetic in Rust. You can write the above code variously as:

// Pre-allocate space, then fill it.
let mut a = Vec::with_capacity(1000);
for i in 0..1000 {
    a.push(i as f64);
}

// Allocate and initialise, then overwrite
let mut a = vec![0.0f64; 1000];
for i in 0..1000 {
    a[i] = i as f64;
}

// Construct directly from iterator.
let a: Vec<f64> = (0..1000).map(|n| n as f64).collect();
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
DK.
  • 55,277
  • 5
  • 189
  • 162
  • 15
    The question asks for an array and provides the C++ equivalent as an example, while this answer instead covers a dynamic collection type. This also spans the first two google results for allocating an array in rust, but I don't believe that this answers the question. – Score_Under Jan 08 '18 at 12:40
  • 3
    @Score_Under: Except the C++ code is using a dynamically-allocated array, so there's almost no practical difference. A direct translation would be unsafe and unidiomatic. Also, considering the original asker accepted the answer as given, I'd say it *does* answer the question they intended to ask. – DK. Jan 08 '18 at 12:46
  • 3
    The array in the question is allocated at runtime, but otherwise it is a fixed array (without the ability to resize, append, etc). Rust does have an equivalent type, and it is required for some standard library functions (e.g. when reading in bulk from a file). – Score_Under Jan 08 '18 at 13:05
  • 1
    @Score_Under: Rust does not, in general, have a way of reliably allocating fixed-sized arrays on the heap, *except* by going through `Vec`, at which point there's not much benefit in getting bogged down talking about types that only have niche uses. Also, there's no indication in the question that the use of a fixed size is even important. As for the standard library requiring fixed-sized arrays, you're going to have to specify because I'm not aware of any. – DK. Jan 08 '18 at 14:32
  • https://doc.rust-lang.org/std/io/trait.Read.html#tymethod.read The `read` method (to perform partial reads of a file) requires an array of u8, and will not accept a vec of u8. The equivalent accepting vec, `read_to_end`, does not allow you to specify the amount of data you wish to read. – Score_Under Jan 08 '18 at 14:46
  • 2
    @Score_Under that is a slice not an array in the function you are referring to `fn read(&mut self, buf: &mut [u8]) -> Result` – Taras Alenin Oct 04 '18 at 02:33
16

It is completely possible to allocate a fixed-sized array on the heap:

let a = Box::new([0.0f64; 1000]);

Because of deref coercion, you can still use this as an array:

for i in 0..1000 {
    a[i] = i as f64;
}

You can manually free it by doing:

std::mem::drop(a);

drop takes ownership of the array, so this is completely safe. As mentioned in the other answer, it is almost never necessary to do this, the box will be freed automatically when it goes out of scope.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 1
    See also [Is it possible to have stack allocated arrays with the size determined at runtime in Rust?](https://stackoverflow.com/q/27859822/155423); [Allocate array onto heap with size known at runtime](https://stackoverflow.com/q/41710952/155423); [Is there any way to allocate a standard Rust array directly on the heap, skipping the stack entirely?](https://stackoverflow.com/q/53691012/155423); [Creating a fixed-size array on heap in Rust](https://stackoverflow.com/q/25805174/155423); [How to allocate arrays on the heap in Rust 1.0?](https://stackoverflow.com/q/30242770/155423), etc. – Shepmaster Apr 15 '19 at 15:11
  • 1
    wouldn't this essentially allocate on the stack first and then pass to the heap? Because it wouldn't work for very large arrays, like 90kb for example – Guerlando OCs Nov 10 '21 at 23:48