Basic question about Juce Arrays

Just started to look into Juce Arrays and they seem quite complex. What would be the main reason to use them instead of std::vector in C++?

I was particuilary confused by the fact that the traditional assignment operators is not used:
At least the way I tried with an int array, like:

Array<int> arr;
...
arr.set(1, 7);

I would have expected: arr[1] = 7; to work but it didn’t. Is set the way to make assignments always in Juce Arrays? I find very little info or practial examples on how to use these arrays.

The array first needs to have enough size for the set method to work :

    juce::Array<int> arr;
    arr.resize(2);
    arr.set(1, 7);
    std::cout << arr[1] << "\n";

But that isn’t any different to std::vector, if you wanted to do vec[1] = 7; the vector would have to have a size of 2 before attempting that.

In any case, using std::vector is probably the more correct choice these days, unless you are extensively working with Juce APIs that actually expect you to use the juce::Array.

1 Like

Sorry, I phrased the question a bit incomplete, the ‘…’ was meant like:

Array<int> arr;
...some stuff to add elements to the array...
arr.set(1, 7);

The actual question was if assignment in Juce arrays always are with an explicit set method and not like traditional for arrays: arr[index] = value_to_assign? Looking at the extensive Array documentation on docs.juce.com I’m not sure if I’ve grasped the concept fully. Besides the assignment question I’m particularly interested in if there’s an arraytype recommended for use inside processorblocks that would be a better choice than standard vectors.

I guess what’s confusing me is that there are things in the Juice API that I maybe not need, where I can use traditional C++, but I’m not sure if that will lead to problems further down on the road.

The “std vs JUCE container” is a question that comes often (JUCE was there from before C++11 birth).

Yes, that’s how it is. operator[] reruns a read-only const reference. I tend to prefer std::vector

Depends a bit on what you actually want to do. If you are accessing pre allocated memory, all containers with continuous storage should probably be just fine, e.g. std::vector, juce::Array or juce::AudioBuffer. Changing the size of any of those containers during your processing callback is always a no-go since it performs heap allocations which you want to avoid during processing. The same goes for creating temporary arrays during processing, using any kind of heap based container should be avoided here, but the stack based std::array is a good option here in case the size is a compile time constant and it’s not too big to blow your stack with a stack overflow.

2 Likes

AFAIK juce::Array operator[] returns a copy ( there ) and thus TomSwirly request linked above.

Ah yes, of course, you are totally right – should have looked at the implementation before posting :grimacing:

1 Like

I would expect a const reference as you. :grin:

Thanks for the explanation. I realize I need to get a better grasp on these memory and realtime related aspects. Maybe Will Pirkles book is a good start?

If you search on this forum you will find a lots of free materials to jump into RT.

Use Timur Doumler’s and Fabian Renn-Giles & Dave Rowland’s talks keyword for instance.

Looks interesting. Thanks.