Pages: [1]   Go Down
Author Topic: malloc bug?  (Read 800 times)
0 Members and 1 Guest are viewing this topic.
USA
Offline Offline
Full Member
***
Karma: 0
Posts: 238
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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 ###
Logged

Finland
Offline Offline
Sr. Member
****
Karma: 1
Posts: 270
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Dallas, Texas
Offline Offline
God Member
*****
Karma: 31
Posts: 887
Old, decrepit curmugeon
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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
}
Logged

New true random number library available at: http://code.google.com/p/avr-hardware-random-number-generation/

Current version 1.0.1

Dallas, Texas
Offline Offline
God Member
*****
Karma: 31
Posts: 887
Old, decrepit curmugeon
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.82 KB - downloaded 6 times.)
Logged

New true random number library available at: http://code.google.com/p/avr-hardware-random-number-generation/

Current version 1.0.1

USA
Offline Offline
Full Member
***
Karma: 0
Posts: 238
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

UK
Offline Offline
Faraday Member
**
Karma: 100
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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...?
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Offline Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

USA
Offline Offline
Full Member
***
Karma: 0
Posts: 238
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

I only provide help via the forum - please do not contact me for private consultancy.

Dallas, Texas
Offline Offline
God Member
*****
Karma: 31
Posts: 887
Old, decrepit curmugeon
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

New true random number library available at: http://code.google.com/p/avr-hardware-random-number-generation/

Current version 1.0.1

USA
Offline Offline
Full Member
***
Karma: 0
Posts: 238
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

I only provide help via the forum - please do not contact me for private consultancy.

Pages: [1]   Go Up
Jump to: