Random data in EEPROM

Hi everyone! I am executing the following code:
main.cpp

#include "../lib/lib2/lib2.h"

using namespace std;

// define pins
#define CTL1 2
#define CTL2 3

LIB2 * eeprom;

void (* reboot) (void) = 0;

void setup() {
    Serial.begin(115200);
    while(!Serial && !Serial.available()) {}
    Log.begin(LOG_LEVEL_VERBOSE, &Serial);

    pinMode(CTL1, INPUT);
    pinMode(CTL2, INPUT);

    eeprom = new LIB2();

    eeprom->initParam("state", sizeof(uint8_t), (uint16_t *)0);
    eeprom->initParam("mode", sizeof(uint8_t), (uint16_t *)0);
    eeprom->begin();

    eeprom->increment("state");
}

void loop() {
    if(digitalRead(CTL1) == HIGH) {
        eeprom->increment("mode");
    }

    if(digitalRead(CTL2) == HIGH) {
        eeprom->reset();
        reboot();
    }
}

lib2.cpp

#include "lib2.h"

using namespace std;

LIB2::LIB2() {}

/**
 * Add parameter
 * @method LIB2::init
 */
void LIB2::begin() {
    if(_DATA.size() <= 0) {
        exit(201);
    }
    firstStart();
    if(!_FIRST_START) {
        readMem();
    }
}

/**
 * [LIB2::firstStart description]
 * @method LIB2::firstStart
 */
void LIB2::firstStart() {
    uint8_t * addr = &_FSBIT;
    uint8_t f = eeprom_read_byte(addr);
    if(f <= 0) {
        Log.notice(F("\n\n::: First start: %d\n"), f);
        _FIRST_START = true;
        reset();
        eeprom_write_byte(addr, 0x0F);
        eepromSave();
    } else {
        Log.notice(F("\n\n::: Not empty:  %d\n"), f);
        _FIRST_START = false;
    }
}

/**
* Reset EEPROM to "defaults"
*/
void LIB2::reset() {
    uint16_t addr = 0;
    uint8_t dump[16];
    memset(dump, 0x00, sizeof(dump));
    while(addr < E2END) {
        eeprom_write_block(dump, (void *)addr, sizeof(dump));
        eeprom_busy_wait();
        addr += sizeof(dump);
    }
}

/**
 * Read data from EEPROM
 * @method LIB2::readMem
 */
void LIB2::readMem() {
    auto i = _DATA.begin();
    for (; i < _DATA.end(); i++) {
        if((i->addr + (i->size * 8)) < E2END) {
            eeprom_read_block(i->value, (void *)i->addr, i->size);
            eeprom_busy_wait();
            Log.notice(F("READ %s = %d from %d -> %d \n"), i->param, i->value, i->addr, i->size);
        }
    }
}

/**
 * Write data to EEPROM
 * @method LIB2::eepromSave
 */
void LIB2::eepromSave() {
    auto i = _DATA.begin();
    for (; i < _DATA.end(); i++) {
        if(_FIRST_START) {
            Log.notice(F("WRITE %s : %d -> %d of %d\n"), i->param, i->value, i->addr, i->size);
            eeprom_write_block(i->value, (void *)i->addr, i->size);
        } else {
            Log.notice(F("UPDATE %s : %d -> %d of %d\n"), i->param, i->value, i->addr, i->size);
            eeprom_update_block(i->value, (void *)i->addr, i->size);
        }
    }
}

/**
 * Update the only parameter
 * @method LIB2::eepromSaveParam
 * @param  param            [description]
 */
void LIB2::eepromSaveParam(const char *param) {
    auto i = _DATA.begin();
    for (; i < _DATA.end(); i++) {
        if(strcmp(i->param, param) == 0) {
            Log.notice(F("UPDATE %s : %d | %d -> %d\n"), i->param, i->value, i->addr, i->size);
            eeprom_write_block(i->value, (void *)i->addr, i->size);
            eeprom_busy_wait();
            break;
        }
    }
}

/**
 * Dummy counter incrementor
 * @method stat
 * @param  param [description]
 */
void LIB2::increment(char const * param) {
    auto i = _DATA.begin();
    for (; i < _DATA.end(); i++) {
        if(strcmp(i->param, param) == 0) {
            i->value = (void *)((uint16_t)i->value + 1);
            Log.notice(F("+ %s = %d\n"), i->param, i->value);
            break;
        }
    }
    eepromSaveParam(param);
}

lib2.h

#ifndef LIB2_H
#define LIB2_H

#include <ArduinoLog.h>
#include <avr/eeprom.h>
#include <vector>

#define eeprom_busy_wait() \
do {} while (!eeprom_is_ready())

class LIB2  {
    public:
String tmp();
        LIB2();
        ~LIB2() {
            eepromSave();
            _DATA.clear();
        };
        void begin();
        void eepromSave();
        void eepromSaveParam(char const * param);
        void reset();
        void increment(char const * param);
        template <typename T> void initParam(char const * param, size_t s, T * value = NULL) {
            _D a;
            if(_DATA.size() > 0) {
                _D pelt = _DATA[_DATA.size() - 1];
                a.addr = pelt.addr + pelt.size;
            } else {
                a.addr = _MEMBIT;
            }
            a.size = s;
            a.param = param;
            a.value = value;
            _DATA.push_back(a);
        };

    protected:
        void readMem();

    private:
        uint8_t _FSBIT = 0;
        uint8_t _MEMBIT = 16;
        struct _D {
            char const * param;
            void * value;
            size_t size = 0;
            uint16_t addr = 0;
        };
        std::vector<_D> _DATA;
        bool _FIRST_START = false;
        void firstStart();
};

#endif

The procedure:

  1. reset eeprom
  2. change parameters
  3. check data that were stored

MCU: atmega328p

Once it reads back parameters from EEPROM, they are anything but required uint16s.
Anyone has an idea where I messed up?
Thanks,

Anyone has an idea where I messed up?

I'd say that you have written far too much code without testing the basics before adding more capabilities.

Test the writing to, and reading from, the EEPROM without the vectors and templates.

Other thread removed as requested.

@way5, thank you.

PaulS:
I'd say that you have written far too much code without testing the basics before adding more capabilities.

Test the writing to, and reading from, the EEPROM without the vectors and templates.

I did, but also tested every step. The value of 0x0F being successfully stored in the address that indicates FSBIT, as well as could be read with no problem. The values of state and mode are stored correctly in vector DATA. The problem or in the eeprom_read* or eeprom_write* that data.

I do found the problem. This is some kind of a delay between the method logic and a real action of eeprom_* functionality.
Basically the solution is to store i->value to an in-class global variable that I named “void * stack”, just before to do read or write actions.
As I understand, the value that stored in vector _DATA, that being found in a loop using iterator, in its turn being destroyed before read or write action takes place.
That is one of the weird things to me which I never read about.

PROBLEM #2:
However, there’s another strange thing. The script increments values of “state” and “mode” on 2, despite the fact that increment() states about:

i->value = ((uint16_t)i->value + 1);

And this happens precisely in this expression.
Any idea why that happens?
Thanks!