It seems like I am wrecking my config_data variable by writing into a location on my structure array. Is this an address issue as my array of structures is growing in size?
Apologies if I missed the solution in another thread.
How did you get that to compile? id_possibilities must be a const expression because the value needs to be set at compile time and can’t be changed at runtime. I’d declare it like:
Be careful with id_tagged_bank_index. You probably should do some bounds checking to make sure it’s >=0 and < id_possibilities to avoid corrupting memory.
While it’s initialized to 0 as a global, if you read the struct from uninitialized EEPROM, that will likely be 0xffffffff, which as an int is -1, which will cause all sorts of memory corruption as an index into idDict.
Also you probably don’t want to use strcpy with things other than string constants because it does not protect against overflowing id which is 19 ASCII character + 1 trailing null.
Thanks Rick, sorry you are correct, I actually have
const int id_possibilities=50;
I think you might have cracked it with id_tagged_bank_index I bet this wasn't initialised correctly which resulted in some odd behaviour in EEPROM. I will add a bounds check to ensure I am getting expected behaviour.
The depths on my ignorance on chars and Strings deepens. Essentially I am trying to set one char array equal to another char array. What would your advice be in this scenario.
One word of caution tho' strncpy() will not zero-terminate the string when the source string is longer than the target buffer.
To tackle that you can "force-terminate" the string like this
strncpy(dest, source, sizeof(dest)-1);
dest[sizeof(dest)-1] = '\0'; // as pointed out by @Muskie below
One side note too
How likely is it that you really need 50 idDict entries and how often may at least one of these change?
In case of a notable mutability of the data it may be worth to consider separating the configuration "header" and the tag "data" to only use that amount of flash you actually need.
For that you could store the actual number of stored tags in the config but store their individual data in a dedicated flash are.
e.g.
typedef struct{
uint32_t magic;
char email[40];
uint8_t id_tagged_bank_index;
uint8_t savedTags;
} eepromConfig;
typedef struct{
char id[20] = "";
uint8_t count = 0;
} idTagged;
const int baseAddr = 100;
const int tagAddr = baseAddr + sizeof(eepromConfig);
eepromConfig config;
...
for(int i=0; i < asOftenAsNeeded; i++) {
idTagged newTag;
// ... populate newTag
EEPROM.put(tagAddr + config.savedTags++ * sizeof(newTag), newTag); // put new tag at next free place (and push index forward)
}
EEPROM.put(baseAddr, config); // write config block
(you may want to add some check to keep the number of possible tags small enough to not outgrow the available flash memory, but you don't need to hardcode that limit)
I also see you are using a magic number scheme to check data integrity. Whenever you read back the data from EEPROM and see a mismatch between your expected magic number and the read one, you should also reset explicitly reset id_tagged_bank_index and savedTags to 0