Why can I not use pointers instead of array with PROGMEM? I'm currently changing some libraries to use flash instead of RAM for string storage so that I do not run out of SRAM on a project.

Some strings in the library are declared in this manner:

const char *testStringA = "ABC";


This is different to how I normally see this done:

const char testStringB[] = "DEF";


However, I think that these two are equivalent when declared const and initialised in the declaration. Both work fine in code.

I attempted to move these to flash:

const prog_char *testStringC PROGMEM = "GHI";


I then found that this didn't work. It was producing gobbledegook when printed.

However, following the more usual pattern of:

const prog_char testStringD[] PROGMEM = "JKL";


works fine.

I can see in the disassembly:

00000068 &lt;testStringC&gt;:
  68:   04 01                                               ..

0000006a &lt;_ZL11testStringD&gt;:
  6a:   4a 4b 4c 00                                         JKL.


So it is clear the pointer and PROGMEM results in the string/array not being initialised.

Why is this?

Example code:

#include &lt;avr/pgmspace.h&gt;

const int BUFFER_LEN = 20;

const char *testStringA = "ABC";
const char testStringB[] = "DEF";
const prog_char *testStringC PROGMEM = "GHI";
const prog_char testStringD[] PROGMEM = "JKL";

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

void loop()
{
    char buffer[BUFFER_LEN];

    Serial.println(testStringA);
    Serial.println(testStringB);

    strncpy_P(buffer, testStringC, BUFFER_LEN);
    Serial.println(buffer);

    strncpy_P(buffer, testStringD, BUFFER_LEN);
    Serial.println(buffer);

    delay(1000);

}
Well, this question has been wisely answered in an answer to Stack&nbsp;Overflow question C: differences between char pointer and array.

Basically, what you're declaring as PROGMEM with,

const prog_char testStringD[] PROGMEM = "JKL";


is both the array and the memory it points to, that is, the elements of the array, both in current's scope stack. Whereas with:

const prog_char* testStringC PROGMEM = "GHI";


you declare a PROGMEM pointer to a constant string that may stay elsewhere in memory, but not declared as a PROGMEM string.

Though I did not test that, but you should try to declare:

const prog_char* testStringC PROGMEM = F("GHI");


to actually allocate the pointed string within the PROGMEM space. I guess it should be working, using Arduino's F() macro, which adds a lot of boilerplate code to actually have the same result as the array declaration.

As said in comments, if not in a global context, the PSTR() macro could be used instead of the F() macro.

Simpler is better: use the array declaration, not the pointer one!

Cf that other answer, the __flash qualifier is a third solution ;-)