Sizeof variables and Due's RAM

I set out to see how much space some arrays have. I used this test code

bool state = false;

uint16_t BuffA;
uint16_t BuffB;
uint16_t BuffC;
uint16_t all = 0;

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

void loop(){
if (state==false){
Serial.println(sizeof(BuffA));
Serial.println(sizeof(BuffB));
Serial.println(sizeof(BuffC));
all = sizeof(BuffA) + sizeof(BuffB) + sizeof(BuffC)
Serial.println(all);
state = true;
}
}

I got this answer from the serial:

92000
40000
40000
40928
1. Why are the results doubled from those i initiated? Shouldn't the first one be 46kb and the other two 20kb?
2. Why is the last value only 40928?
3. The RAM of Due is 96kb. Does this mean that with the initialization of only three arrays it's almost full? Ifi crossed the RAM limit, would the IDE throw an error?
4. If i still need more RAM, can i use and external one with Due for high speed RAM acquisition?

sizeof doesn't return the number of elements. It returns the number of bytes. Since they are uint16_t arrays each element is 2 bytes - hence twice the size.

The reason your last number is only 40928 is because of integer wraparound. You only provide a 16-bit unsigned variable to store it in, so all you get is the lower 16 bits of the answer.

92000 + 40000 + 40000 = 172000

172000 in hex is 0x29FE0

0x29FE0 truncated to 16 bits is 0x9FE0

0x9FE0 in decimal is 40928.

The RAM of Due is 96kb. Does this mean that with the initialization of only three arrays it's almost full? Ifi crossed the RAM limit, would the IDE throw an error?

It would, but you aren't actually using the arrays for anything, so the compiler threw them away.

If i still need more RAM, can i use and external one with Due for high speed RAM acquisition?

There are ways of interfacing the SAM3X with external RAM, but I don't thing the Due exposes all the signals you need. I would change to a chip with more RAM, such as the PIC32MZ with 512kB of RAM and 200MHz operation.

• OP should be extremely careful with using nearly all RAM for data on embedded systems. One won’t get a nice error when things overflow. Instead, the stack will grow into the data section, overriding data there and getting overwritten by write access’ to the data. One will be seeing erratic misbehaviour, including freezes, NMIs and incorrect data. – Jonas Schäfer Jul 12 '17 at 17:28
• Also known as "stack smashing" ;) – Majenko Jul 12 '17 at 17:41

The sizeof operator's result is number of bytes, not number of array elements. Your arrays in the program above have two bytes per element, hence twice as many bytes as elements.

If you want to report the number of elements, divide the total size by the number of bytes per element. For example:

nElements = sizeof BuffA /  sizeof BuffA;

As uint16_t variables have 16 bits, the total all will exceed the maximum (65535) that all can hold. Consider using uint32_t type for that variable. For example:

uint32_t all = sizeof BuffA/sizeof BuffA + sizeof BuffB/sizeof BuffB + sizeof BuffC/sizeof BuffC;

Because the type of sizeof is size_t, a “type able to represent the size of any object in bytes”, one need not cast any of addends to uint32_t for the result to not overflow.

1. A variable of uint16_t has 16 bits, thus two bytes, so for e.g. BuffA this means 46000 * 2 = 92000 bytes.

2. The variable all is also 16 bits and can contain only as max value 65,535. 92000 + 40000 + 40000 = 172000 bytes but that does not fit in 16 bits. Therefore the value is clipped ... make it a uint32_t variable.

3. The total is 172.000 bytes, this mean it will not fit in 96KB. What are the value ranges you want to store? If the values are max 255

4. You can use extra RAM. DRAM is very hard to use, EEPROM is only usable when you don't have to write it too often. Otherwise use SRAM, e.g. the 23LC1024's which can store 128 KB RAM and are only DIP8.

• Thanks! About the external SRAM.. I am doing real time audio applications. Will the external RAM introduce delays to the output audio? – user1584421 Jul 12 '17 at 15:35
• I did some timing tests on the 23LC1024 ... a page read/write of 32 byte costs about 100 us. Reading other amount cost relatively more, like 1 byte read or write: 23 us, 8 bytes 30 us, 1024 bytes 4000 us. I also tested another SRAM, but that was much slower and more DIP pins, but cheaper. – Michel Keijzers Jul 12 '17 at 15:56
• 32 byte is pretty small, so maybe the time for read/write is high! To put this into perspective, do you know how much time it would take for 32 byte r/w on the arduino due? Is there some benchmarking info on this? – user1584421 Jul 12 '17 at 16:07
• True, but for 1024 bytes its relatively larger (note that 1024 bytes / 32 * 100 ns = 3200 us. Of course you can read multiple times 32 bytes. I also am interested about a bench mark for the Arduino (Uno/Mega). But I don't know if it can be found. – Michel Keijzers Jul 12 '17 at 16:36
• I will ask for further info on this and i will answer here if i know something. Thanks for everything! – user1584421 Jul 12 '17 at 16:39