[RESOLVED] Strings cause arduino to crash :(

I'm working on a program that will display time on 2 8x8 matrices and also show scrolling message (i.e. current date).
It works, except after about an hour everything just freezes. I think it's running out of memory somehow, and I pretty much traced it to these lines of code:

myDate=monthShortStr(month())+ String(" ") + day() + String(", ") + year() + String (" ");     
scrollText (myDate,myDate.length());

If instead of myDate I pass some predefined string, it works and doesn't freeze. For example:

String myText = "hello world";
scrollText (myText,11);

Can someone help me out with it? What am I doing wrong?
Here's snips of code so you can see what's happening:

String myDate;

void loop() { 
    buttonProc();
    displayHour();
    displayMinute(0);

// Show Date every minute on 10 second mark
  if ( second()==10 ) {
    myDate=monthShortStr(month())+ String(" ") + day() + String(", ") + year() + String (" ");  
   scrollText (myDate,myDate.length());
}

void scrollText(String myString, int sizeofstring){

 Some more code goes here...

}

I'm attaching whole sketch just in case, but it's pretty lengthy...

LED_clock_test6.ino (8.83 KB)

The String class uses memory. Plenty. I think you have found the problem - even without looking at the code. When you get close to running out of memory the crashes will be "random" as the stack and the "heap" start overwriting each other, and that means the amount of overwriting is very sensitve to excatly what variables are used and what calls are being made and when an interrupts (which also uses stack) occurs.

Search for and include one of the "report free memory" routines ( fex. memoryFree ) to confirm your diagnosis.

Solving the problem? Use less strings, or put them into the EEPROM memory. Maybe a fixed array where you insert/overwrite some positions with the values to avoid using the String class for string concatonation.

Solving the problem? Use less strings,

Or better yet, don't use Strings at all.

Use null terminated char arrays, also known as strings.

And learn about "PROGMEM".

Arrch:

Solving the problem? Use less strings,

Or better yet, don't use Strings at all.

Use null terminated char arrays, also known as strings.

How? Would someone snow me an example of combining strings, integers, and more strings into a char array? That's what I'm looking for, still haven't found an example :frowning:
I basically need to create 12 letter string or char array that will contain date taken from time.h library in format like: "Jan 01, 2012".

I did learn PROGMEM, it's in my sketch (to store big Font). I don't see a reason to store 12 character string in PROGMEM. Problem is not lack of RAM, problem is that somehow variables increase in size with each loop...

bratan:
How? Would someone snow me an example of combining strings, integers, and more strings into a char array? That's what I'm looking for, still haven't found an example :frowning:
I basically need to create 12 letter string or char array that will contain date taken from time.h library in format like: "Jan 01, 2012".

sprintf()

I basically need to create 12 letter string or char array that will contain date taken from time.h library in format like: "Jan 01, 2012".

char dateString[16];
int day = 1;
int year = 2012;
char *month = "Jan";
sprintf(dateString, "%s %02d, %d", month, day, year);

You forgot to leave space for the null terminator.

You forgot to leave space for the null terminato

I counted the characters 3 times before I hit Post. I still got it wrong. I'll fix that!

PaulS:
I counted the characters 3 times before I hit Post. I still got it wrong. I'll fix that!

I was wondering if you was going to fix it to 13, or 16...You used 16, is there a reason? I often see people using multiples of 4 but I don't understand why :slight_smile:

Maybe to avoid memory fragmentation?

guix:
I was wondering if you was going to fix it to 13, or 16...You used 16, is there a reason? I often see people using multiples of 4 but I don't understand why :slight_smile:

If we're not careful, we'll have to worry about a Y1M!

I was wondering if you was going to fix it to 13, or 16...You used 16, is there a reason? I often see people using multiples of 4 but I don't understand why

No particular reason. Any even number will work. The compiler will not store a non-byte sized value at an odd address, so the odd count would waste a byte anyway.

Strings cause arduino to crash :frowning:

@bratan: Did you read this?

Read this before posting a programming question

In particular:

Warning: In versions of the Arduino IDE up to 1.0.1 (at least) there is a bug in dynamic memory allocation. This affects both malloc/free and new/delete. In particular it also affects the String class, which uses dynamic memory allocation. This is discussed in this forum thread. That thread mentions a work-around (replacement free() function) until the inbuilt libraries are updated.

Please note that, at present, the String library has bugs as discussed here and here.

In particular, the dynamic memory allocation used by the String class may fail and cause random crashes.

I recommend reworking your code to manage without String. Use C-style strings instead (strcpy, strcat, strcmp, etc.).

PaulS:

I basically need to create 12 letter string or char array that will contain date taken from time.h library in format like: "Jan 01, 2012".

char dateString[16];

int day = 1;
int year = 2012;
char *month = "Jan";
sprintf(dateString, "%s %02d, %d", month, day, year);

PaulS, Arrch thank you so much!!!
I will give it a try!
Nick, sorry about that, I didn't notice that :slight_smile: Thanks for letting me know about the bug!

Edit: It totally works, you guys rock, thanks so much!!! :slight_smile:

sprintf(dateString, "%s %02d, %d ",monthShortStr(month()),day(),year());

It's my experience that you should never use dynamic memory allocation (operator new, malloc, or things that use them) on microcontrollers. There's just too much that can go wrong with fragmentation, heap running into stack, interrupts, etc.

Fixed buffers are the way to go. If you need to call "new" to create something, use placement new:

#include <new>

char storage[sizeof(MyThing)];
MyThing *ptr = new(storage) MyThing(arguments);

Also, some other things mentioned in this thread:

  • An array of charais actually a byte-sized (or rather, byte-aligned) piece of data. This will have sizeof() 6:
  struct stuff {
    char a[3];
    char b[3];
  };
  • A fixed-size array does not use heap. It uses global data segment space (if global/static) or stack space (if local.) There is no risk of fragmenting either.

jwatte:
It's my experience that you should never use dynamic memory allocation (operator new, malloc, or things that use them) on microcontrollers. There's just too much that can go wrong with fragmentation, heap running into stack, interrupts, etc.

I have seen that usually the bugs and issues tend happen in the freeing of memory.
So using things like malloc() tend to be ok for memory buffers that are never released.

--- bill