# Fixed-capacity vector utility class?

**URL:** <https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936>\
**Category:** Development\
**Created:** [October 19, 2018, 2:23pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936 "2018-10-19T14:23:31Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![CrushedPixel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/crushedpixel/32/8654_2.png) [@CrushedPixel](https://forum.juce.com/u/CrushedPixel)\
**Post date:** [October 19, 2018, 2:23pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/1 "2018-10-19T14:23:31Z")

</div>

Since memory allocations on the heap are [not realtime-safe](http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing), one must not grow `std::vector`s (or `juce::Array`s) beyond their initial capacity in the audio thread. `std::array`s are not always feasible, as they don’t provide `erase` or `push_back` functionality due to being fixed-size.

Does JUCE provide a container that provides this functionality, but can’t grow beyond its initial capacity?  
There’s [`boost::container::static_vector<T,Capacity>`](https://www.boost.org/doc/libs/1_59_0/doc/html/boost/container/static_vector.html), but I don’t want to include the boost library in my project.

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [October 19, 2018, 2:27pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/2 "2018-10-19T14:27:03Z")

</div>

Yes, the [Array](https://docs.juce.com/develop/classArray.html#details) class can do that for trivially copyable objects.

---

<div class="post-metadata">

**Author:** ![CrushedPixel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/crushedpixel/32/8654_2.png) [@CrushedPixel](https://forum.juce.com/u/CrushedPixel)\
**Post date:** [October 19, 2018, 2:31pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/3 "2018-10-19T14:31:42Z")

</div>

How exactly does it work? I looked at the documentation for `Array` before, but didn’t find any such functionality.

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [October 19, 2018, 2:38pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/4 "2018-10-19T14:38:56Z")

</div>

Outside the audio thread you can call [Array::ensureStorageAllocated (elements)](https://docs.juce.com/develop/classArray.html#a5099340060ffbc6170c4b8d3936ff8d5), which will allocate the needed space.

The objects are then copied in place as a memory copy, avoiding allocation if possible.

---

<div class="post-metadata">

**Author:** ![CrushedPixel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/crushedpixel/32/8654_2.png) [@CrushedPixel](https://forum.juce.com/u/CrushedPixel)\
**Post date:** [October 19, 2018, 2:40pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/5 "2018-10-19T14:40:15Z")

</div>

That doesn’t guarantee I can’t grow the capacity, though, which is something I’m looking for.  
In that case, I may as well use an `std::vector` and call `reserve` in the constructor.

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [October 20, 2018, 10:35am UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/6 "2018-10-20T10:35:34Z")

</div>

Can’t you just make sure your size always stays the same via a jassert or something?

---

<div class="post-metadata">

**Author:** ![CrushedPixel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/crushedpixel/32/8654_2.png) [@CrushedPixel](https://forum.juce.com/u/CrushedPixel)\
**Post date:** [October 20, 2018, 11:53am UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/7 "2018-10-20T11:53:41Z")

</div>

Sure, but that would require me to add a `jassert(vec.size() < vec.capacity())` before every single call to `push_back` and similar, which is quite tedious. It would have been cool to have this functionality baked directly into `juce::Array`, perhaps via a subclass/template parameter, which enables assertions before every allocation if desired.

In the meantime, I’m just very careful when coding to not grow vectors (but everyone knows that saying “I’ll just be careful here” never works out), and use a profiler to find hidden `malloc`s.

---

<div class="post-metadata">

**Author:** ![PeterRoos](https://avatars.discourse-cdn.com/v4/letter/p/7ab992/32.png) [@PeterRoos](https://forum.juce.com/u/PeterRoos)\
**Post date:** [October 20, 2018, 11:56am UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/8 "2018-10-20T11:56:40Z")

</div>

Why not use a HeapBlock that you resize in prepareToPlay() ?

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [October 20, 2018, 12:01pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/9 "2018-10-20T12:01:25Z")

</div>

> [@CrushedPixel](#):
>
> In the meantime, I’m just very careful when coding to not grow vectors (but everyone knows that saying “I’ll just be careful here” never works out), and use a profiler to find hidden `malloc` s.

I agree, it’s a pain. But it is the only way IMHO, since if you would force it not to grow, what should be the consequence? Buffer dropout? throw an exception?  
The only thing that can work, is to design your code around, so it doesn’t want to grow.

---

<div class="post-metadata">

**Author:** ![CrushedPixel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/crushedpixel/32/8654_2.png) [@CrushedPixel](https://forum.juce.com/u/CrushedPixel)\
**Post date:** [October 20, 2018, 12:02pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/10 "2018-10-20T12:02:12Z")

</div>

Because a `HeapBlock`, similar to an `std::array`, has a fixed size (which equals its capacity) and therefore I can’t dynamically add or remove elements from it.

---

<div class="post-metadata">

**Author:** ![CrushedPixel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/crushedpixel/32/8654_2.png) [@CrushedPixel](https://forum.juce.com/u/CrushedPixel)\
**Post date:** [October 20, 2018, 12:02pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/11 "2018-10-20T12:02:48Z")

</div>

A simple `jassertfalse` would be enough for me. This way the operation doesn’t fail, but I am notified that it allocated memory and I should re-think my design.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [October 20, 2018, 12:53pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/12 "2018-10-20T12:53:29Z")

</div>

My practical advice would be to use a normal array, but preallocate enough space that you don’t expect it to ever hit capacity. Then add some checks to assert if it does so you can re-think your reservation size.

The thing is that if you did use a special array that couldn’t reallocate, but you don’t expect that situation to ever really happen, then how does it help? If an overflow means that your code has to fail, then that’s a worse outcome than just using a normal vector which does an allocation and carries on running. Obviously it’s not safe to allocate, but there’s a very high chance that if you do a single emergency allocation, nobody will ever notice.

---

<div class="post-metadata">

**Author:** ![CrushedPixel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/crushedpixel/32/8654_2.png) [@CrushedPixel](https://forum.juce.com/u/CrushedPixel)\
**Post date:** [October 20, 2018, 12:59pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/13 "2018-10-20T12:59:08Z")

</div>

That’s exactly what I suggested - if the Array could be configured to call `jassertfalse` when allocating, the program would still run as intended, but I, as the developer, get notified about the issue without having to do overflow checks myself.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [October 20, 2018, 1:06pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/14 "2018-10-20T13:06:57Z")

</div>

Oh right. Hmm, I don’t really see that as a responsibility of the Array - a better approach would probably be to intercept all allocation calls and check whether they’re on the audio thread, which would catch many other more subtle mistakes than just this very specific use-case.

---

<div class="post-metadata">

**Author:** ![CrushedPixel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/crushedpixel/32/8654_2.png) [@CrushedPixel](https://forum.juce.com/u/CrushedPixel)\
**Post date:** [October 20, 2018, 1:09pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/15 "2018-10-20T13:09:07Z")

</div>

That sounds indeed pretty useful.  
Can you point me in the right direction, how to do that?

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [October 20, 2018, 1:25pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/16 "2018-10-20T13:25:28Z")

</div>

One thing came to my mind, when investigating options, if Array would allow to query it’s allocated size, you could easily do also the jassert route:

```auto
jassert (array.allocatedSpace() >= array.size() + numElementsToAdd);

```

but intercepting a level below is also a quite nice option.

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [October 21, 2018, 6:05pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/17 "2018-10-21T18:05:20Z")

</div>

I’ve implemented a test for this in pluginval and a utility class to go along with it.

> **[Tracktion/pluginval](https://github.com/Tracktion/pluginval)**
>
> Cross platform plugin testing and validation tool. Contribute to Tracktion/pluginval development by creating an account on GitHub.

The test checks for allocation in the audio thread whilst processing.

---

<div class="post-metadata">

**Author:** ![CrushedPixel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/crushedpixel/32/8654_2.png) [@CrushedPixel](https://forum.juce.com/u/CrushedPixel)\
**Post date:** [October 21, 2018, 8:50pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/18 "2018-10-21T20:50:58Z")

</div>

Amazing!  
I’ll check that out right now.

---

<div class="post-metadata">

**Author:** ![CrushedPixel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/crushedpixel/32/8654_2.png) [@CrushedPixel](https://forum.juce.com/u/CrushedPixel)\
**Post date:** [October 21, 2018, 9:32pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/19 "2018-10-21T21:32:12Z")

</div>

This is weird - I’ve built an unoptimized version of my plugin in debug mode, including an intentional heap allocation to see if your plugin detects it, but here’s what happens:

 ![49](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/e/ec65dbfa594128f3db95b7a5804e6c211379b81e.png)

As you can see on the left, `pluginval` says “all tests completed successfully”, while XCode Instruments finds the `malloc`… (I profiled the execution of `pluginval`)

I’m using the latest Release (v0.1.4) for macOS from Github.  
In headless mode, I get the same result, although the `AllocatorInterceptorTests`, presumably testing `pluginval` itself, pass.

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [October 21, 2018, 10:17pm UTC](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936/20 "2018-10-21T22:17:50Z")

</div>

That’s odd, if it’s going through operator new it should be caught. Can you tell me what’s doing the allocation? There are a couple of different operator new’s, it might be using a different one.

[Next page](https://forum.juce.com/t/fixed-capacity-vector-utility-class/29936.md?page=2)
