Global variables and memory

Assume the following global variables:

classNameA   dataA;
classNameB   dataB;
float        aFloatValue;
uint32_t     anotherVariable;

Is the memory allocated continues? So if there is an error in classNameA that write/update one byte too much, dataB will be corrupted?

No, the compiler can put them anywhere and perhaps the compiler decides to not use a memory location but to keep that variable in registers.

A 'struct' packs all the variables one after the other. Only then the next variable will be corrupted if too much data is written to a previous variable.

Your question seems strange. How can the code from a class write too much data to its object ? Then there must be something very wrong. Sometimes a class allocated extra memory from the heap and a bug might cause to overwrite other data in the heap.

1 Like

I'm asking because I suspect memory corruption causing restart. I have checked every line of code but cannot find where this happens. If I know how the variables are located in memory I might find where this happens.

Debugging the restart is time consuming since this happens after several days of uptime.

Can you post your code?

35000 lines of code?

That is EXTREMELY long.
You can paste it into a google doc and publish it to the web and post the link.
(Don't think the web will actually see it from searching it up though)

First, I don't use google doc.

Second (and most important), the code is not relevant since my question is about how the compiler organize variables in memory (so any code can be used as an example as long as it use global variables).

Third, I doubt that anyone will spend a week trying to figure out IF and WHERE memory is overwritten.



It does not take a week. If a few of us spend half an hour to scroll through the code to check if something gets our attention, then you might know more.
It is very common that one overlooks a bug in his or her own code. I think you need someone else to look at it.
You can get rid of a bug by rewriting the whole sketch with a different approach. In your case, you could rewrite the most questionable part.

With so many code, you should have the different sections very well separated and have the code organized in a very good way.

If you are sure that you don't write beyond an array, then the bug does not have to be with a previous variable. A problem with a pointer or stack can cause data to be written to anywhere in the SRAM.
If you change the compiler options and the behavior is totally different, then at least you can be sure that it is a (nasty) bug.

I have used a week looking after possible errors in my code to find out if I overwrite variables, but I have not found anything.

So it might be in a library. It happens shortly after I close a file on the SD card and open a new one. Sometime it cause a crash less than a second after a new file was created. Sometime it does not crash but sensors start giving errors.

Also noticed that if the controller does not crash after creating a new file, the new file is always empty even if the size() method claim that it should contain data (file size is shown on a LCD display)

About changing compiler options - is there any settings I should change?

The Arduino sets the option "-Os" for minimal code size. You could change that in the platform.txt.

About the problem with the SD library is good information.
That library needs a lot of ram for the FAT32 filesystem.

Have you installed a "special" or "improved" version of a normal library ?

Which SD library do you use (a link to it, the version, and so on, there are many versions of the SD library). Do you accidentally have a other SD library in your "libraries" folder ?
Which Arduino board do you use ?
Can you add code to check runtime the amount of free SRAM ?
What does the compiler say about the SRAM usage ?

From the README.adoc file in the SD library folder:

 Copyright (C) 2009 by William Greiman
Copyright (c) 2010 SparkFun Electronics

if that help.

I changed "Compiler warings" to ALL and got this on the SD library:

C:\Users\dahls\Documents\Arduino\libraries\SD\src\SD.cpp: In function 'open.constprop':

C:\Users\dahls\Documents\Arduino\libraries\SD\src\SD.cpp:462:14: warning: 'pathidx' may be used uninitialized in this function [-Wmaybe-uninitialized]

     filepath += pathidx;


C:\Users\dahls\Documents\Arduino\libraries\SD\src\SD.cpp:456:9: note: 'pathidx' was declared here

     int pathidx;


From the compiler:

Sketch uses 184674 bytes (72%) of program storage space. Maximum is 253952 bytes.
Global variables use 4387 bytes (53%) of dynamic memory, leaving 3805 bytes for local variables. Maximum is 8192 bytes.

and I have added a function that show available memory during runtime. It is never under 1300 bytes free. I'm using a Mega2560.

While @Koepel is correct, there are no guarantees about memory layout, assuming there is nothing special about the four things, the linker will lay them out in the order they are found: dataA, dataB, aFloatValue, anotherVariable.

Correct. Based on the aforementioned assumptions.

If you want to know how the variables are arranged, you could create a debug-output in setup() and print their addresses to the serial monitor.

Already done but not tested.

Just found out that it might be the SD card itself that is the problem. Not possible to access it anymore from a PC or a camera. So I'll try with a new one.

Have you read this: Don't Format SD cards with OS utilities!

What kind of SD module do you have ? Part of a Ethernet shield ?
The SD card should get 3.3V signals.
But some SD cards are not compatible anyway.

The shield runs on 5 V. It's a standalone shield. New micro SD card just installed. Time will tell if it works.

BTW, the addresses for the objects/variables are NOT in the same order as the declaration.

Some SD modules don't have a level shifter. You need a level shifter to convert the Arduino 5V signals to SD 3.3V signals.

That's usually the case. If you need a fixed order of some variables, you must use a struct.

The SD card adapter I got has a level shifter :slight_smile: