Mutable global state isn't a problem, only shared mutable global state may be (for instance when the global state is writable from unexpected places in the code base or from other threads).
There's a lot of problems that can be solved just fine with an upfront defined fixed memory layout in a global static variable.
Dismissing globals is basically the same problem as sweeping generalizations like "goto considered harmful", "avoid for-loops" or "almost always auto" - such statements can serve as advice for newbies, but following the advice blindly can also lead to less elegant and less maintainable solutions.
Global mutable state is still terrible design unless actually necessary. Any function at all in your entire program can change the state of the thing which makes it very difficult to debug and reason about.
In all languages I'm aware of you can limit the visibility of global variables to the current compilation unit / source file, it's still 'mutable global state' from the pov of functions in that file, but non-existent for anything outside the source file.
> (for instance when the global state is writable from unexpected places in the code base or from other threads)
...or from a function that calls itself, directly or indirectly. This automatically becomes possible basically whenever the function accesses a user-supplied callback. So you'll run into issues unless you have full control over your callees, or only access the global array in logically-atomic patterns.
(To give an ancient example: to enable function calls, PDP-8 programs allocated a word of static memory before the top of each subroutine to store the return address. However, if a subroutine tried to recurse into itself, then the old return address would be overwritten, and it would never be able to return properly. Supposedly this could result in very gnarly errors to debug.)