How to tell if an array is too big?

Hello,

is there a native way without external libs to tell if creating a new array is safe without causing funny behaviour at runtime?

I have a pretty simple code: create an uint8_t array[9000], iterate through it filling the memory with 0xCAFEBABE (i know, i know, but c’mon, the IDE is java so it’s fine, even more since i neither like bad babes nor dead beef. i prefer chicken), print every byte to serial and after that is done print the first byte of the array:

void setup() {
  Serial.begin(9600);
  while (!Serial) {
  }

  Serial.println("Serial ready!");
}

void loop() {
  uint8_t as[9000];
  uint8_t ad[4] = {0xCA, 0xFE, 0xBA, 0xBE};

  for (int i = 0; i < 9000; i++) {
    as[i] = ad[i % 4];
//  }
//
//  for (int i = 0; i < 9000; i++) {
    Serial.print(i);
    Serial.print(": ");
    Serial.println(as[i], HEX);
  }

  Serial.println("Done!");

  //Serial.println(as[0], HEX);

  delay(5000);
}

this works even through 8192, the sram size of the mega 2650 i’m trying it on and finally prints “Done!”

if i uncomment the second for loop it stops working and just prints ?S?i?.. and keeps printing question marks, just that the question marks are mirrored which the forum doesn’t let me paste.

if i comment the second loop out again and uncomment the println above the delay it prints just “Se” (without timestamp while it is enabled in the serial monitor) and does nothing else.

so do i see right that there is nothing guarding the memory already claimed by other variables?

and how could i know before overwriting anything if it’s safe to use the whole array?

If you make the arrays global, the compiler will tell you how much memory you’re using.

The IDE does not report the amount of memory used by local variable, only global variables.

Clearly a 9000 byte array will not fit on a Mega, which only has 8192 bytes of memory.

I suspect that the code is able to run with the single for loop because the compiler is very good at optimizing code and can determine that the reference to as[ i ] can be completely eliminated, and thus completely eliminates the array.

sorry i wasn’t clear, i meant during runtime.

gfvalvo:
If you make the arrays global, the compiler will tell you how much memory you’re using.

and the compiler even tells me if it’s too big for the board :slight_smile: but i want to set the size at runtime

david_2018:
The IDE does not report the amount of memory used by local variable, only global variables.

Clearly a 9000 byte array will not fit on a Mega, which only has 8192 bytes of memory.

I suspect that the code is able to run with the single for loop because the compiler is very good at optimizing code and can determine that the reference to as[ i ] can be completely eliminated, and thus completely eliminates the array.

since i want to build the array at runtime on the arduino i can’t use the IDE anyway.

i chose the 9k size for testing because it’s guaranteed to be too big, to see if i get any hint that it failed or at least that it’s not safe to use it.

not sure how much the compiler does here. my idea is that the arduino just sets the index back to 0 once it reached the end of the available memory address range, overwriting the 808 bytes difference between the onboard memory and array twice?

the question is: how could i check before using an array if it interferes with other variable’s personal space?

You could use malloc and check to see if it was successful. Generally, dynamic memory allocation is a bad idea on a small micro controller, but you might get away with it here.

Usually, the advice is to create the biggest array you anticipate you will need to start with - saving RAM by using less if you don't need it doesn't help if there's nothing else to use it.

frozenrat:
sorry i wasn't clear, i meant during runtime.

and the compiler even tells me if it's too big for the board :slight_smile: but i want to set the size at runtime

since i want to build the array at runtime on the arduino i can't use the IDE anyway.

Why do you want to do it this way? What problem are you trying to solve?

If you look at a library such as Arduino-MemoryFree/MemoryFree.cpp at master · mpflaga/Arduino-MemoryFree · GitHub
you can copy the code if just using a library is against your religion.

frozenrat:
sorry i wasn't clear, i meant during runtime.

since i want to build the array at runtime on the arduino i can't use the IDE anyway.

There is nothing in the IDE that prevents you from declaring an array within a function whose size is unknown at compile time. The array will allocate space on the stack, and cease to exist when you exit the function.

There is no way any compiler can warn you that a runtime allocation of memory will be too large, because it has no way of knowing the size.

countrypaul:
If you look at a library such as Arduino-MemoryFree/MemoryFree.cpp at master · mpflaga/Arduino-MemoryFree · GitHub
you can copy the code if just using a library is against your religion.

ideology please, not religion, i don’t serve some library-deity. i have my reasons but since this subject is just as flammable as others back in the day vi != vim != emacs i prefer not to elaborate on that :wink:

i’ve seen that such libs exist. i am not convinced it’s really that safe…

gfvalvo:
Why do you want to do it this way? What problem are you trying to solve?

reading byte arrays. yes, user input - bleh - but since i make the protocol up i could send the size of the array before and make sure to have a buffer near that is large enough to hold what is coming.

wildbill:
Usually, the advice is to create the biggest array you anticipate you will need to start with - saving RAM by using less if you don’t need it doesn’t help if there’s nothing else to use it.

now thinking a step or two ahead… that means… i would just claim as much memory as possible and manage it myself. next i want a garbage collector and if i do a good job most code will be swallowed the moment it gets uploaded.

well, space is already pretty limited, so eating a big chunk right from the start and not giving it away… isn’t that attractive to me. but i get that borrowing space at runtime just when it’s needed isn’t such a great idea?

I do this on a daily basis... a ‘known size’ array may seem wasteful, but there’s that inevitable occasion when your memory use and the need for ‘more’ will intersect!
The real answer is to add external memory (user input is slow), or bump up to a larger microcontroller.

A “too big” array will not wrap around; it will collide with other things that are in RAM.
The avr has no memory protection and will not detect this. Bad and unpredictable things are likely to happen.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.