Declare a global array when its size is only available at run time

Is it possible to declare a globally available array when the number of elements will only be available at run time?

Thanks
Paulo

Yes, you can use malloc() to get the necessary memory. Take care that your array doesn't get to big!

pcborges:
Is it possible to declare a globally available array when the number of elements will only be available at run time?

Thanks
Paulo

It can be done, but usually when you show someone who knows what they're doing the specific situation they can show you a better way where you don't have to. Remember, there's no use in saving memory that you can't use because it might be needed for a bigger array on the next run.

Ok, I am not that advanced.
Let's see:

I declare an global array on top of my sketch (before setup(){ ):

String imagePath;

Then on setup() I will get the info that I have, say, 24 imagePaths to deal with (say "/image01.jpg" to "/image24.jpg")

After some research I found some info about the subject and got something like this:

int * heapArray =(int ) malloc(arrayLengthsizeof(int));

Now I see no correlation of how can I apply this to my imagePath array.

Help welcome.
Thanks

What type of Arduino are we talking about?

Don't use String on AVR Arduinos!

BTW, Delta_G's comment is absolutely true, use a dynamic array of C++ objects is quite tricky and should not be used small MCUs. In bigger C++ projects you'd use container classes (p.e. vector) for this.

String **imagePaths;

...

int numberOfPaths = 24;

imagePaths = (String **) malloc(numberOfPaths * sizeof(String *));

...

imagePaths[0] = new String("TestString");

pcborges:
Ok, I am not that advanced.

Then the smart thing for you to do would be to declare that array to be large enough to hold the maximum number of elements and just leave it that way. Then you can have another variable that tells how many things are actually there.

Thanks Delta_G,

I thought about that, may be 128…
But then wouldn’t I be wasting too much memory is the typical value was around 12?

Hi there pylon,
I believe it will do the job, it is a Mega but I am thinking about migrating the project to ESP32.
One doubt:
In the sizeof(String *));
Should I then put the expected size of, for instance: “/image01.jpg” = 12?
Would it be this: imagePaths = (String **) malloc(numberOfPaths * 12); ?
Thanks

pcborges:
Thanks Delta_G,

I thought about that, may be 128...
But then wouldn't I be wasting too much memory is the typical value was around 12?

OK, but what are you going to do with that memory then? This isn't a PC. There aren't other programs running that can use it. And if you try to use more memory somewhere else in your program and then one day try to malloc for 128 entries in that array then suddenly you have a crash. That's what noobies invariably end up doing with malloc, is trying to use the same memory for two things.

It does no good to save that memory if you will still need to make sure that it is available. If it needs to be held for those strings then hold it for those strings. There's no sin in not using it all. If you want to save memory to use for something else then you have to think about how to make those things smaller or less of them.

sizeof (String*) . . . is a constant.
sizeof (String) . . . is also a constant.

Don’t confuse the size of the class with the length of the string.

In the Arduino IDE, you have access to the Himem area of a ESP32 - WROVER, that would allow you to get about a 4MB array. I use Himem to store any buffers I may use, such as serial receive buffer.


The ESP32 has a built-in OS called freeRTOS. The freeRTOS API has an Espressiff addition called 'ring buffer' see API reference: (FreeRTOS Additions - ESP32 - — ESP-IDF Programming Guide latest documentation and freeRTOS has the stream buffer RTOS stream buffer API functions that might be of interest to you when moving around large bits.

Would it be this: imagePaths = (String **) malloc(numberOfPaths * 12); ?

No, the array is an array of String pointers, so one element has the size of a pointer, the compiler knows that while compiling. The size of the contained string value isn't needed at that time as the String class is allocating and deallocating it on the fly. That's the reason you shouldn't use it on an AVR Arduino (as the Mega2560 is!).

From where are you getting the data at run time?

It looks like you might be making a copy of an SD card directory listing. Since that data is on the SD card you should be able to read it from the SD card when you need it, without having to keep a copy in memory.