When I declare the size of each array in my sketch and compile it, the Arduino IDE gives me the percentage of dynamic memory used by the sketch. If I don't explicitly declare the size of each array, that size goes down when I compile the sketch. It seems this might be a way to avoid the warnings about running out of memory ... but I have a bad feeling about this.
What are the potential pitfalls of NOT declaring the size of each array in my sketch?
It may occasionally work, depending on other variables.
Using such a notation is exactly the same as defining an array with a size of 10, but using up to 20 elements
if you are going to store data in an array type structure at some point you have to reserve memory for it
It seems like there is a 4th option here - to let the MCU manage the memory allocation. Probably a bad idea.
Sounds like a wrong assumption.
It's not an assumption. I'm just changing the code to either define or not define the size of the arrays and I see a reduction in dynamic memory allocation reported by the compiler.
Actually, in my experience declaring the size and trying utilize space outside of the defines area yields a different result than not defining the array at all.
When you get further with the sketch you are working on and all kindsa tots inexplicable hell starts breaking loose, revisit the idea that anything like what you describe as working was at all. Working.
You just lucky now. Luck shoukd not enter into writing code that works, really works.
There are multiple ways that an array can be constructed and initialized.
For a line like const int myArray[]={1, 2, 3}; the compiler could see that you needed 3*sizeof(int) bytes, then place those values in PROGMEM and link that address for every reference. "One and done".
Another way (without using const) is to allocate the bytes, take the values that were compiled into the code and copy them to the reserved memory.
Similarly, the compiler could allocate memory at runtime startup (data section or on stack) and copy the values. In both of these last two examples, two copies of your data exist, one in the program section, a copy in the data section (or on the stack) and additional code that runs before setup() is linked in to perform the initialization.
If you only ever mean to read those array values, create them using const. Not all boards can utilize the values straight from the code section, but even without using the PROGMEM macro, the AVR and many other boards get compiled into program memory automatically if you use the const specifier.