Issue with OwnedArray and setBounds

Hello,
I am making a plugIn with several filters, each filter is in a class that inherits from component so it is able to process samples but also it can be displayed by its own so I can easily add several filters on the GUI as “cards”.

To do this I use a OwnedArray like so :

OwnedArray<myClass> filters;

then in the editor I fill it and make each of them visible in a loop like so :

myClass newFilter1 = myClass();
myClass newFilter2 = myClass();
audioProcessor.filters.add(&newFilter1);
audioProcessor.filters.add(&newFilter2);
for (size_t i = 0; i < audioProcessor.filters.size(); ++i)
{
    addAndMakeVisible(audioProcessor.filters[i]);
}

but where it go wrong is in the resized function :

void InterpolationFilterAudioProcessorEditor::resized()
{
    int numberOfCards = audioProcessor.filters.size();
    float w = getWidth();
    float h = getHeight();
    float cardWidth = w / numberOfCards;

    for (size_t i = 0; i < numberOfCards; ++i)
    {
        if (audioProcessor.filters[i] != nullptr)
        {
            audioProcessor.filters[i]->setBounds(i * cardWidth, 0, cardWidth, h);
        }
    }
}

The issue comes from the : audioProcessor.filters[i]->setBounds(... part.
The standalone app does open but it does not display anything (I just put a label on each filter that should be on screen), then when I resize the window it crashes.

I think this is very much related to this topic that says it is related to nullptr and undefined behavior:

https://forum.juce.com/t/exc-bad-access-when-setting-bounds/25918/3

but I couldn’t figure out a way to correct my code by reading it.

Can anyone figure it out ?

Welcome to pointers… and lifetimes… so, first issue is that you are declaring your filter objects locally, which means when you exit the function this code is in, the filter objects will be deleted. So any further access to them, outside of that function, will be accessing bad pointers. Second, and not related, is the first two lines are strange. To declare variable of a given type we generally do

myClass newFilter1;

But, as I indicated, this is not what we want for adding to an OwnedArray, since we want a pointer to an object whose lifetime will be controlled by OwnedArray.

Since you don’t need to store the pointers to the filters anywhere except the OwnedArray, you can get rid of the first two lines and do the allocation and assignment in the add call.

audioProcessor.filters.add(new myClass);
audioProcessor.filters.add(new myClass);

Lastly, combining your UI and backend code may be easy, but it is generally a poor choice from an archetecture perspective.

Ok thanks for the reply,
That make sens indeed, I will try to declare otherwise. This is silly because I actually did not intend to put that here later, I wanted to do a quick test to know if the plugin would run.
Good to know tho I was not aware of that behavior.

Hello,
So I have done the assignment inside the add function and it does work ! Concerning the combination of UI and backend, do you have a standart way to do it ? I don’t want to create too many objects as I create a filter because they could be quite numerous.

You may create filters in the backend (processor) and pass a reference to the UI (editor).