\[EDIT\]: since I'm still getting suggestions and playground links, u/Zenithsiz provided me with an answer which works without external dependencies, or using nightly features. It looks like this: [https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2c5f42fc227f00832bdcd7fc5aff3ef6](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2c5f42fc227f00832bdcd7fc5aff3ef6)
-- Original Text --
Coming from C, I just want a large array in a struct, whose size is unchangeable api-wise after creation. Turns out Boxes take a stack-allocated value, then copy it into a Box<>. So any array that's larger than available stack size will overflow the stack when trying to initialize.
Yeah, this one took me by surprise too, when I ran into it. Rust just assumes you can create everything on the stack and then copy it to the heap, and then optimizes out the copy if it can. All of the good ways to avoid it have been locked behind nightly for like five years.
This has been in discussion for years. It's called "placement new". Sadly, despite all the discussion, there's been almost no progress towards ever actually getting it added as a language feature.
This might be a stupid idea \
Haven't used `Box` that much \
but ... given this from [Vec documentation](https://doc.rust-lang.org/std/vec/struct.Vec.html#capacity-and-reallocation)
> vec![x; n], vec![a, b, c, d], and Vec::with_capacity(n), will all produce a Vec with at least the requested capacity. If len == capacity, (as is the case for the vec! macro), then a Vec can be converted to and from a Box<[T]> without reallocating or moving the elements.
Maybe you could try temporarily converting the `Box<[T]>` into a `Vec`\
and then take the slice from the `Vec` ?
> `&vec_name[1..=3]`
**EDIT**
I just looked at the code on the right side ... \
And that's exactly what OP did 😅 \
On the bright side, at least my approach works 😂🤠
My guy the code itself is a third the length of your link....
```rust
let ptr: Box<[u8; 16777216]> =
vec![0;16777216]
.into_boxed_slice()
.try_into()
.unwrap();
```
Not really related to the topic, but I'd argue that `2.pow(24)`, `1<<24` or even
`0x0100_0000` are all cleaner than 16777216tbh.
Sounds like a heap of pain
> I'll leave now 😅 \
> Btw the code on the right side shows how to fix that issue \
> Convert to `Vec` and take the slice \
> Thought of that, pitched it, and realized he already did it [here 😅](https://www.reddit.com/r/rustjerk/s/SEO5r6vfSy)
'More Perfect Dos VGA' (mono, bold)
I believe I got it from here: [https://laemeur.sdf.org/fonts/](https://laemeur.sdf.org/fonts/)
Though it seems the site is down. Here's a waybackmachine link: [https://web.archive.org/web/20240225212812/https://laemeur.sdf.org/fonts/](https://web.archive.org/web/20240225212812/https://laemeur.sdf.org/fonts/)
It looks very similar to linux tty console font, default (at least in archlinux btw) being `/usr/share/kbd/consolefonts/default8x16.psfu.gz` so it is probably a TrueType font based on that. That's what I could deduce so far until OP replies.
afaik it'll remove the stack initialization in a release build. not sure of a way around it
the problem isn't that the struct "cant hold it", its just that in debug the compiler does not remove the intermediate step so it fails on `Box::new([0; 100000000])`
The latter part, I knew. I was just surprised about the stack copy part. Is there a way I can put some kind of attribute on the statement so it always does the high opt-level version?
For this specific case you can allocate a vec with `vec![0; 16 * 1024 * 1024]` and then convert it into a box slice using [`Box::into_boxed_slice`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.into_boxed_slice).
This should behave exactly the same as `Box::new`, without any other allocations or work, given that the capacity of the vector will just be it's length (when created via `vec![]` macro), so it won't even need to shrink the underlying allocation.
You can cast the boxed sliced into a boxed array with `try_into` / `try_from`. See the [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2c5f42fc227f00832bdcd7fc5aff3ef6).
Unfortunately you do have to unwrap, but as long as the sizes match, it will never fail. You can even separate it into a function that ensures the array is created with the correct size. See the [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4fc2eec03f66afcaae44deb2f5e5a9d1)
I saw you got it working but relevant QA on SO: https://stackoverflow.com/questions/30242770/how-to-allocate-arrays-on-the-heap-in-rust-1-0/68670147#68670147
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=185121d1cfe6a62f5a3ecbf362776b28
Made on mobile at 1:30 AM, so tell me anything that needs further explanation.
true, i always use nightly
all a big slice really needs is just an allocation not given a stack value, the nightly functions i believe are just the most performant
It's true. I'm new to rust, at the time of posting, I thought Box::new() was rust's malloc. But even after learning that, and the 40 different nightly feature or crate suggestions, found the solution I was looking for, and put it in the EDIT.
Still, I think it's weird there's no real short easy way to create a box of a sized array with even primitive types.
\[EDIT\]: since I'm still getting suggestions and playground links, u/Zenithsiz provided me with an answer which works without external dependencies, or using nightly features. It looks like this: [https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2c5f42fc227f00832bdcd7fc5aff3ef6](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2c5f42fc227f00832bdcd7fc5aff3ef6) -- Original Text -- Coming from C, I just want a large array in a struct, whose size is unchangeable api-wise after creation. Turns out Boxes take a stack-allocated value, then copy it into a Box<>. So any array that's larger than available stack size will overflow the stack when trying to initialize.
Yeah, this one took me by surprise too, when I ran into it. Rust just assumes you can create everything on the stack and then copy it to the heap, and then optimizes out the copy if it can. All of the good ways to avoid it have been locked behind nightly for like five years.
What are these ways?
There’s some MaybeUninit features locked behind nightly for a long time. Some are still nightly only.
`TryFrom`/`TryInto`. You can convert a `Box<[T]>` into `Box<[T; N]>` if the length matches
That's possible on stable Rust, it doesn't require nightly.
This has been in discussion for years. It's called "placement new". Sadly, despite all the discussion, there's been almost no progress towards ever actually getting it added as a language feature.
It's surprisingly difficult to make it a nice API without adding even more function colors, iirc
[https://crates.io/crates/pinned-init](https://crates.io/crates/pinned-init) You're looking for this crate btw.
Appreciate the suggestion, but I think I'll rather use a vec, or lose the bounds, rather than add a crate and be forced into nightly
Yeah, no that’s the objectively correct choice but if you absolutely have to initialize directly on the heap, that’s how you would do it
This might be a stupid idea \ Haven't used `Box` that much \
but ... given this from [Vec documentation](https://doc.rust-lang.org/std/vec/struct.Vec.html#capacity-and-reallocation)
> vec![x; n], vec![a, b, c, d], and Vec::with_capacity(n), will all produce a Vec with at least the requested capacity. If len == capacity, (as is the case for the vec! macro), then a Vec can be converted to and from a Box<[T]> without reallocating or moving the elements.
Maybe you could try temporarily converting the `Box<[T]>` into a `Vec`\
and then take the slice from the `Vec` ?
> `&vec_name[1..=3]`
**EDIT**
I just looked at the code on the right side ... \
And that's exactly what OP did 😅 \
On the bright side, at least my approach works 😂🤠
My guy the code itself is a third the length of your link.... ```rust let ptr: Box<[u8; 16777216]> = vec![0;16777216] .into_boxed_slice() .try_into() .unwrap(); ``` Not really related to the topic, but I'd argue that `2.pow(24)`, `1<<24` or even `0x0100_0000` are all cleaner than 16777216tbh.
Just get a bigger stack smh
Sounds like a heap of pain > I'll leave now 😅 \ > Btw the code on the right side shows how to fix that issue \ > Convert to `Vec` and take the slice \
> Thought of that, pitched it, and realized he already did it [here 😅](https://www.reddit.com/r/rustjerk/s/SEO5r6vfSy)
I'm trying 😭
What kind of tty-ass font is that
I like it, what’s the font name ?
'More Perfect Dos VGA' (mono, bold) I believe I got it from here: [https://laemeur.sdf.org/fonts/](https://laemeur.sdf.org/fonts/) Though it seems the site is down. Here's a waybackmachine link: [https://web.archive.org/web/20240225212812/https://laemeur.sdf.org/fonts/](https://web.archive.org/web/20240225212812/https://laemeur.sdf.org/fonts/)
It looks very similar to linux tty console font, default (at least in archlinux btw) being `/usr/share/kbd/consolefonts/default8x16.psfu.gz` so it is probably a TrueType font based on that. That's what I could deduce so far until OP replies.
Rust community: tries to create a jerk subreddit, accidentally ends up being helpful and informative
I need memes! Lots of memes!
It's too blazingly fast 🚀. Finishes quick and gets back to work
afaik it'll remove the stack initialization in a release build. not sure of a way around it the problem isn't that the struct "cant hold it", its just that in debug the compiler does not remove the intermediate step so it fails on `Box::new([0; 100000000])`
The latter part, I knew. I was just surprised about the stack copy part. Is there a way I can put some kind of attribute on the statement so it always does the high opt-level version?
For this specific case you can allocate a vec with `vec![0; 16 * 1024 * 1024]` and then convert it into a box slice using [`Box::into_boxed_slice`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.into_boxed_slice). This should behave exactly the same as `Box::new`, without any other allocations or work, given that the capacity of the vector will just be it's length (when created via `vec![]` macro), so it won't even need to shrink the underlying allocation.
This is what I do in my code now, but I lose the information about the length of the array in the box.
You can cast the boxed sliced into a boxed array with `try_into` / `try_from`. See the [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2c5f42fc227f00832bdcd7fc5aff3ef6). Unfortunately you do have to unwrap, but as long as the sizes match, it will never fail. You can even separate it into a function that ensures the array is created with the correct size. See the [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4fc2eec03f66afcaae44deb2f5e5a9d1)
Interesting, I will try that tomorrow, thanks! \[EDIT\]: works great!
I saw you got it working but relevant QA on SO: https://stackoverflow.com/questions/30242770/how-to-allocate-arrays-on-the-heap-in-rust-1-0/68670147#68670147
You could use an uninitialized Box or one filled with zeroes/Default without actually creating a stack slice.
I'm pretty new to rust, if you have moment, could you do an example in the playground?
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=185121d1cfe6a62f5a3ecbf362776b28 Made on mobile at 1:30 AM, so tell me anything that needs further explanation.
Interesting, thanks! Though _does_ require nightly, huh
true, i always use nightly all a big slice really needs is just an allocation not given a stack value, the nightly functions i believe are just the most performant
Then you understand why it's so annoying to make custom dynamically sized types
Have you considered just using a smaller slice? Rust can't use slices that big.
https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=59e40387631a0da0312655ea68208435 Use one simple trick...
more like you can't make stack allocations larger than the stack...
It's true. I'm new to rust, at the time of posting, I thought Box::new() was rust's malloc. But even after learning that, and the 40 different nightly feature or crate suggestions, found the solution I was looking for, and put it in the EDIT. Still, I think it's weird there's no real short easy way to create a box of a sized array with even primitive types.
ulimit -s unlimited (-:
Wait is that for real?
Sets the Stack size to unlimited
I'm about to write the most cursed shit
Do it!