malloc bug?

Can someone explain why availableMemory() always returns the same value regardless of the size of buffer?

volatile char buffer[1000];

int availableMemory() {
  int size = 4096;
  void *buf;
  while (!(buf=malloc(--size)));
  free(buf);
  return size;
}

void setup() {
  Serial.begin(9600);
#ifdef USBCON
  while (!Serial);
#endif
  Serial.println( availableMemory() );
}

void loop() {}

The code has been adapted from Arduino Playground - AvailableMemory

Perhaps the compiler optimizes buffer off because you don't use it.

Not a bug in malloc, the code your provided is simply doing what you told it to do.

int availableMemory() {
  int size = 4096;                       // You have assigned a value of 4096, which btw wouldn't work on a typical arduino which has 2k or less of ram, you must be doing this on a MEGA
  void *buf;
  while (!(buf=malloc(--size))); // Call malloc to allocate 4095 bytes (4096 - 1) and go into a loop attempting to allocate one less byte until it succeeds
  free(buf);
  return size;                             // Return whatever size value was successfully allocated by malloc.  On a chip with more than 4095 bytes it returns 4095
}

pekkaa:
Perhaps the compiler optimizes buffer off because you don't use it.

From the attached disassembly of the sketch, that appears to be what happened.

sketch_jun28a.cpp.lst (64.8 KB)

Oh, that tricky compiler... if I change loop() to the following, availableMemory() will return a different value based on the size of buffer.

void loop() {
  for (int i=0; i<sizeof(buffer); ++i)
    buffer[i] = 0;
}

mkwired:
Can someone explain why availableMemory() always returns the same value regardless of the size of buffer?

volatile char buffer[1000];

int availableMemory() {
 int size = 4096;
 void *buf;
 while (!(buf=malloc(--size)));
 free(buf);
 return size;
}

void setup() {
 Serial.begin(9600);
#ifdef USBCON
 while (!Serial);
#endif
 Serial.println( availableMemory() );
}

void loop() {}



### The code has been adapted from http://arduino.cc/playground/Code/AvailableMemory ###

Surely that is going to return the maximum contiguous available block of memory, not the total available memory...?

majenko:
Surely that is going to return the size of the maximum contiguous available block of memory, not the total available memory...?

majenko:

mkwired:
Can someone explain why availableMemory() always returns the same value regardless of the size of buffer?

volatile char buffer[1000];

int availableMemory() {
 int size = 4096;
 void *buf;
 while (!(buf=malloc(--size)));
 free(buf);
 return size;
}

void setup() {
 Serial.begin(9600);
#ifdef USBCON
 while (!Serial);
#endif
 Serial.println( availableMemory() );
}

void loop() {}



### The code has been adapted from http://arduino.cc/playground/Code/AvailableMemory ###

Surely that is going to return the maximum contiguous available block of memory, not the total available memory...?

Of course.

My goal is to find away to determine how large a buffer can be once my program is finished. I need to collect as much data as possible and transmit it once full. I'm somewhat concerned about the stack running into the buffer.

mkwired:
Can someone explain why availableMemory() always returns the same value regardless of the size of buffer?

I'd expect that to return the size of the first successfully allocated buffer. What makes you think it doesn't?

wanderson:

pekkaa:
Perhaps the compiler optimizes buffer off because you don't use it.

From the attached disassembly of the sketch, that appears to be what happened.

I don't often need to look at assembler, but I had a look at your listing because I was intrigued to see how the compiler could legitimately optimise out the malloc() calls. It doesn't look to me as if it would be a reasonable thing to do, and I couldn't see anything in the assembler to suggest that it had done. Did I misunderstand you?

It didn't optimize out the malloc, but rather the original volatile char buffer[1000]; And while a listing, it does provide assembler out :slight_smile:

PeterH:

mkwired:
Can someone explain why availableMemory() always returns the same value regardless of the size of buffer?

I'd expect that to return the size of the first successfully allocated buffer. What makes you think it doesn't?

Would you think the second and third call to largestBufferSize() in the following code would return 16000? Will it does. I know size is too big for the microcontrollers in question, but the first call to largestBufferSize() works as expected. I changed the function name to make it somewhat clearer in what it is exactly doing.

volatile char buffer[100];

int largestBufferSize() {
  int size = 16001; // I know this is too big
  void *buf;
  while (!(buf=malloc(--size)));
  free(buf);
  return size;
}

void setup() {
  Serial.begin(9600);
#ifdef USBCON
  while (!Serial);
#endif
  Serial.println( largestBufferSize() );
}

void loop() {
  volatile char buffer2[100];
  Serial.println( largestBufferSize() );
  for (int i=0; i<sizeof(buffer); ++i)
    buffer[i] = 0;
  for (int i=0; i<sizeof(buffer2); ++i)
    buffer2[i] = 0;
  Serial.println( largestBufferSize() );
  for (;;);
}

mkwired:
Would you think the second and third call to largestBufferSize() in the following code would return 16000? Will it does.

No, I didn't expect that. That suggests that yo have successfully allocated 16000 bytes, which seems unlikely unless you have external RAM. What pointer did malloc() return?