String and RAM usage

Hi,

If I use this:

#define mystring "Very Long String Very Long String Very Long String Very Long String Very Long String Very Long String"
Serial.print(mystring );

Will mystring be using up RAM the entire time?

Thanks

Yes. If you want to avoid it google for "PROGMEM".

Udo

Will it? Considering that it's a #define, that isn't any different from

Serial.print("A very long string has lots of characters");

I'm not disagreeing with you, or saying you're wrong. I don't know where the constant strings get stored, or what there scope and/or lifetime is.

Let me elaborate more then...

#define mystring "Very Long String Very Long String Very Long String Very Long String Very Long String Very Long String"
#define anotherstring "Very Long String Very Long String Very Long String Very Long String Very Long String Very Long String"
#define P(name) static const prog_uchar name[] PROGMEM
void printP(const prog_uchar *str) {
char a;
do {
a=pgm_read_byte(str++);
if (a!=0) Serial.print(a);
}
while (a!=0);
}
...
P(myMsg) = mystring anotherstring ;
printP(myMsg);

Would mystring and anothertring be using up RAM?

I don't know where the constant strings get stored, or what there scope and/or lifetime is.

Without any adornments (like PROGMEM; which may be the only one) string constants end up in both Flash and SRAM.

SRAM is divided into four sections...

  • Uninitialized data. This area is filled with zeros before main is called. Global / static variables without an initial value are in this section.

  • Initialized data. This area is copied from Flash to SRAM before main is called. Global / static variables with an initial value are in this section. String constants are also in this section.

  • Stack. The stack pointer is set to point to the start of the stack but no other initialization is performed.

  • Heap. Only present and managed if malloc and it's kin are included.

Would mystring and anothertring (myMsg) be using up RAM?

No.

Thanks :slight_smile:

The compiler only knows about RAM. All data, unless specially declared (with PROGMEM) is stored in RAM. Initialized data also has a copy in Flash, used to initialize the data in RAM. The early startup code (normally invisible even to the Arduino-level functions) copies (initializes) all the initialized data from flash to RAM before the sketch starts.

Have a look at this sketch to illustrate the implications:

void setup()
{
  Serial.begin(9600);
  Serial.println("constant string");
  strcpy((char *) "constant string", "variable string");
  Serial.println("constant string");
}

void loop() {}

Of course this considered bad practice. So you usually do not find this as an example in the textbooks.

Udo

To show why it's bad practice, look at this example:

void setup()
{
  Serial.begin(9600);
  Serial.println("constant string");
  Serial.println("the string number 2");
  strcpy((char *) "constant string", "variable stringyyyy");
  Serial.println("constant string");
  Serial.println("the string number 2");
}

void loop() {}

Here's what you get:

constant string
the string number 2
variable stringyyyy
yyy

The two strings are stored in subsequent ram locations.
When you copy a longer string onto the first one, the exceeding chars overwrite the second string. The first "y" overwrites the null string terminator.