Why isn't Malloc failing?

I recently came across the malloc function. I wanted to test my understanding of it so I created a simple sketch, where I expected the memory allocation to fail. Here's the sketch:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello");
  uint8_t *buf = (uint8_t *)malloc(600000);
  
  if(buf == NULL){
      Serial.println("Memory Allocated Failed");
  }
  else{
    Serial.println("Memory test Passed");  
  }
}

The issue is, this sketch doesn't fail. I'm using an adafruit bluefruit nRF52832. According to the IDE it has a max of 52224 bytes of dynamic memory. My assumption was that it would return a null pointer because I'm trying to allocate more memory than there is but the serial monitor keeps printing: "Memory Test Passed". Please explain why it is passing.

Why would you assume that?

Check the docs or the source code to learn what actually happens. Keep in mind that any action taken should be based on the board you have selected in the IDE.

malloc() has returned a null pointer on failure to allocate since before K met R.

1 Like

See above. Arduino is freeware.

My assumption on what it would return is based on reading the docs. Haven't found anything that has suggested it behaves differently on different boards.

Well, then, file an issue with the developers of the Adafruit nRF52832 board description for failing to follow the standard.

Memory management is, in general, very poor in Arduino-land. You know exactly how much memory you have, and it isn't much, so use it very wisely.

Well, then, file an issue with the developers of the Adafruit nRF52832 board description for failing to follow the standard.

Can't tell if you're joking or trolling, regardless this isn't very helpful.

Memory management is, in general, very poor in Arduino-land. You know exactly how much memory you have, and it isn't much, so use it very wisely.

Neither is this, but thanks anyway.

No, I'm not trolling, but I probably expected too much insight from you.

There is no operating system on Arduinos, no garbage collection and no memory management. Use of malloc() is strongly discouraged, because of severe limitations on memory and the unpredictability of collisions between heap and stack.

Arduino is a collection of stuff contributed by hundreds, if not thousands of people, covering several dozens of boards and manufacturers, with different CPUs, amounts of RAM and program memory.

There is no one to hold any contributor to accepted standards for C/C++. But, it is all FREE for the download, so you are getting much more than what you pay for.

Good luck with your learning curve!

This number is not a valid (16 bit) int. Append UL and try again.

You are not requesting 600,000 bytes, you are requesting only 9 bytes. This might work better:

uint8_t *buf = (uint8_t *)malloc(600000UL);

nRF52832 is an ARM processor, so I wouldn't think that would be the case. But, you never know. It's worth a try. Otherwise, try this and see what it prints:

void setup() {
  Serial.begin(115200);
  Serial.println("Hello");
  uint8_t *buf = (uint8_t *)malloc(600000);
  Serial.println((uint32_t) buf, HEX);
}

void loop() {
}

How do you figure 9 bytes?

Even if malloc took a 16-bit unsigned integer (which it doesn't), 600,000 would be truncated to 10,176. malloc takes a size_t which on Arm is a 32-bit unsigned integer. malloc should return null in this case since it definitely should know that it can't satisfy a 600,000 byte allocation, even without taking the stack and BSS and such into account.

It is worth noting that if the OP had started with, say, a genuine Arduino Uno R3 (minus the silly integer error mentioned above), we never would have had this discussion.

This works as expected, according to the textbook theory:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello");
  uint8_t *buf = (uint8_t *)malloc(10000);
  
  if(buf == NULL){
      Serial.println("Memory Allocated Failed");
  }
  else{
    Serial.println("Memory test Passed");  
  }
}
void loop(){}

I think the odds of a random Arduino user finding such an egregious fault in the implementation of malloc is about the same as the odds of a random Arduino user finding an egregious fault in the compiler. malloc has been implemented thousands of times on thousands of thousands of platforms over the last 50-60 years, and the implementer would have to be truly, massively, galactically incompetent to screw it up as badly as it being suggested here.

1 Like

I suppose some platform dependent implementation of the NULL macro could also be responsible. In strange cases it is always worth looking first in Arduino.h and ensure compiler warnings are enabled in the IDE.

1 Like

Did you actually try running this code on your UNO?

coz I did and it did returned "Memory Allocated Failed" as expected! :+1:

I guess in IDE when compilng it has no way of cross-referencing the various board memory sizes against the actual code to return any potential memory related issued! :wink:

When using the 'Uno' simulation in Wokwi, I get:

Memory Allocated Failed

It behaves as expected with an ARM STM32F411CEU6 (blackpill) with 128K RAM

Dog bites man.

a7

Howzabout try a few things:

  1. PRINT the result of the malloc
  2. Instead of one massive request, make a number of smaller ones, and PRINT the return values
  3. Write a simple function to PRINT out the memory linked list at the start, and again after each call to malloc. Then we can SEE exactly what is happening.

This will eliminate speculation, and provide actual, factual data.

1 Like