[RESOLVED - my bad!] Problems with OwnedArray under ARM/M1

I recently added support for building universal binaries of my plugin, and am testing under ARM on my new M1 Mac Mini. I use an OwnedArray to store polymorphic objects (the base class or one of three derived classes). This is all working fine on the PC and on Intel Macs or under Rosetta on M1s. But when run using the ARM processor, pretty much every add or remove I make to the array trashes it somehow, leading to bizarre behaviors and eventually a crash.

I’m using the 6.1.4 JUCE SDK. Are there any known issues with OwnedArray under ARM? At this point, everything seems so totally screwed up that I’m looking at maybe ditching OwnedArray altogether and rewriting all of that code to use something from the standard library like a vector or list.

Are you sure OwnedArray itself is the problem?

It sounds more plausible to me that it’s how you used the array. For example adding/removing from OwnedArray will invalidate the iterators, and in case of those being accessed from multiple threads there could certainly be weird things happening.

I personally don’t use OwnedArray in my own code, but it’s in a huge amount of commonly used JUCE classes which work fine on M1, so I’d be really surprised if it’s the direct cause of the bug you’re experiencing.

1 Like

Yep, sure enough, it was me. IN one place in my huge code base, I had used a std::unique_ptr, and used get() on it to add it to the array. Part of “modernizing” my code base. Restored that one place to using a raw pointer, and it is working again. No idea why this only caused a problem. on M1/ARM, but happy to have found the issue. A note I read here about using std::unique_ptr with OwnedArray led me to search for that. This forum is a godsend!

Yeah, I know, I could have changed it to .release(), but no reason for a unique_ptr in only this one location and none of the other functions that access that array.

Not sure if I got it right, but the most “correct” way – at least the way that is probably closest to how std::unique_ptr is intended to be used from my point of view is moving it when you transfer ownership from one instance to another or to some instance that is capable of taking over ownership by passing a unique ptr to it like the juce::OwnedArray is:

struct Foo {};
struct Bar : Foo {};

juce::OwnedArray<Foo> array;
std::unique_ptr<Bar> bar;

array.add (std::move (bar));

Beneath being technically safe, to me code like that is very explicit about ownership to the reader.

3 Likes

Ah, right. Still not used to unique_ptrs. But since all my other code for this array uses raw pointers, no need to use a unique_ptr in this one function only, so I reverted it to a raw pointer for now.