Go Down

Topic: malloc bug? (Read 925 times) previous topic - next topic

mkwired

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

Code: [Select]

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 ###

pekkaa

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

wanderson

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

Code: [Select]

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
}
New true random number library available at: http://code.google.com/p/avr-hardware-random-number-generation/

Current version 1.0.1

wanderson


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.
New true random number library available at: http://code.google.com/p/avr-hardware-random-number-generation/

Current version 1.0.1

mkwired

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

Code: [Select]

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

majenko


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

Code: [Select]

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...?

WizenedEE

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

mkwired



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

Code: [Select]

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.

PeterH


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?



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?
I only provide help via the forum - please do not contact me for private consultancy.

wanderson

It didn't optimize out the malloc, but rather the original
Code: [Select]
volatile char buffer[1000];  And while a listing, it does provide assembler out  :)
New true random number library available at: http://code.google.com/p/avr-hardware-random-number-generation/

Current version 1.0.1

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.

Code: [Select]

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 (;;);
}

PeterH


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?
I only provide help via the forum - please do not contact me for private consultancy.

Go Up