Question on Objects and Strings

I am trying to create an object to represent a menu entry, which a user will see displayed on a small TFT screen and make a selection.

However, I don't think I am storing my strings right and they end up getting garbled when both displayed to serial and to the TFT.

Header:

class MenuEntry {
private:
    int id;
    const void* label; // void to handle both flash memory pointers and pointers to Strings
    bool flash;// flag to determine if pointer is flash or String
    bool clearDataOnDestruct = true;
    
    MenuEntry(int idIn, const void* labelIn, bool isFlashIn);

public:
    /**
     *  don't use, for handling arrays of MenuEntries
     */
    MenuEntry();
    
    MenuEntry(int idIn, const String* labelIn);
    MenuEntry(int idIn, const char* labelIn);
    
    MenuEntry(int idIn, const __FlashStringHelper * labelIn);
    
    int getId();
    
    bool isFlash();
    
    const String* getLabelStr();
    
    const __FlashStringHelper* getLabelFlash();
        
    ~MenuEntry();
};

Implementation:

MenuEntry::MenuEntry(){
}


MenuEntry::MenuEntry(int idIn, const void* labelIn, bool isFlashIn){
    id = idIn;
    label = labelIn;
    flash = isFlashIn;
}


MenuEntry::MenuEntry(int idIn, const String* labelIn){
    MenuEntry(idIn, labelIn, false);
}
MenuEntry::MenuEntry(int idIn, const char* labelIn){
    String* labelStr = new String(labelIn);
    MenuEntry(idIn, labelStr);
}
 
MenuEntry::MenuEntry(int idIn, const __FlashStringHelper * labelIn){
    MenuEntry(idIn, labelIn, true);
}


int MenuEntry::getId(){
    return id;
}

bool MenuEntry::isFlash(){
    return flash;
}

const String* MenuEntry::getLabelStr(){
    return (const String*)label;
}
    
const __FlashStringHelper* MenuEntry::getLabelFlash(){
    return (const __FlashStringHelper*)label;
}

MenuEntry::~MenuEntry(){
    
}

Example of Usage:

const char* dir = "/";
  const int numFiles = getNumFilesInDir(dir);
  MenuEntry* entries = new MenuEntry[numFiles];
  
  writeSerialLine(F("created arr of entries"));
  File root = SD.open(dir);
  writeSerialLine(F("Opened root"));
  
  writeSerialLine(F("Getting File List"));
  CUR_TAB_LEVEL++;
  {
    int i = 0;
    File curEntry;
    do {
      curEntry = root.openNextFile();
      const char testResult = validFile(&curEntry);
      if(testResult == -1){
        break;
      }
      if(!testResult){
        continue;
      }
      
      entries[i] = MenuEntry(i, curEntry.name());
      writeSerial(i);
      writeSerial(F(" "));
      
      // string that comes back is garbled
      String* labelStr = entries[i].getLabelStr();
      writeSerial(&labelStr);
      i++;
    }while(true);
  }
  ...

I assume that I am missing an aspect of Memory Management in C, and that the char arrays are not being kept around after the initial pointer set. Could anyone nudge me in the right direction?

You already have a thread on this. Why do you open a new one ?

It felt different enough a question to warrant a new thread, to me. The question is now less dealing with flash memory and now the semantics of how memory operates concerning the storage of pointers in objects

Ah, the old "priming read" problem. I suggest, instead of the

do {
//yadda
if (someCondition) break;
//yadda2
while(1);

Make a function

define yadda() { yadda }

then say

yadda()
while someCondition is false {
yadda()
//yadda2
}

Of course, it's important that there is some guarantee that 'someCondition' will become false. In the case of an EOF the universe kind of supplies the guarantee. :slight_smile: