Char array weird behaviour

So I was trying to read some phone numbers from an external EEPROM but started getting junk. After some examining I realized that the problem is not with the EEPROM or i2c, it is with the character array.
I tried different ways of filling up the array but always got junk, until I commented a line after the array operations.

At first I thought that the Arduino was running out of memory, but after commenting out and erasing some code the error persisted.
My next resort was to get the pointer address and try to see what is in memory.
Basically when I tried to print out the char array with Serial it seems that it starts a bit back in memory, in the screenshots 24 bytes back, but also had it happen 27 bytes back.
I stripped most of the code, so this is some minimal code where the error persists.

I am using Arduino uno, tried with 2 arduinos.

Here is the code with the error

Here it is without the error (line 73 is commented, and is after the string related code)

At p2 ,getting string length, without the comment I get 27(wrong), with comment we get 3(correct).
At p3 ,printing, w/o comment I get “⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮ttt”, w/ comment we get “ttt”.
I assume this is because print starts a few bytes back - the selected byte in the hex editor.
At p4 ,printing address, w/o comment I get 232 (the selected byte in the hex editor) which although wrong makes sense, w/ comment I got 2280 which I don’t understand why(maybe register address?).
At p5 ,printing directly from memory, in both cases we get “ttt”.
At p6 & p7 I either get the both correct or both wrong.

Also, if I comment the bottom line(73) and uncomment the line under p1(54) I get the same error. This also randomly happens when commenting out other function calls around the code.

This is the same with and without connecting anything on the board.

In the code there are empty functions. That’s because if I have an empty function call the error is there, but if I remove the call to the function the error goes away.

#include "extEEPROM.h"

extEEPROM extEEPROM(kbits_4, 1, 16, 0x50);

#define NUMBER_LENGTH 12

#define EEPROM_SIZE 512

void read_number(int index, char *out_num) {
    int slot_base = index * NUMBER_LENGTH;
    
    for (int i=0; i<NUMBER_LENGTH; i++) {
        char data =  extEEPROM.read(slot_base + i);
        out_num[i] = data;
        
    }
    out_num[NUMBER_LENGTH] = 0;
}

bool is_registered(char *in_num) {
    int num_slots = EEPROM_SIZE % NUMBER_LENGTH;
    
    char read_num[NUMBER_LENGTH];
    
    for (int i=0; i<num_slots; i++) {
        read_number(i, read_num);
        
        if (/*strncmp(in_num, read_num, NUMBER_LENGTH) == 0*/1) {
            /*mem*/Serial.print("m-");Serial.println(freeRam());
            return true;
        }
    }
    return false;
}
/************************************************************************************************/
int freeRam () {
  /*extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);*/
}
/************************************************************************************************/

void setup() {
    
    Serial.begin(9600);
    
    byte i2c_eeprom_stat = extEEPROM.begin(extEEPROM.twiClock100kHz);
    if ( i2c_eeprom_stat != 0 ) {
        Serial.println(F("\nI2C Problem\nFreezing"));
        //while (1) {}
    }
    
    Serial.println(is_registered("+38947888888"), DEC);
    //Serial.println(is_registered("+38947888888"), DEC);
    
    char num[20] = "ttt\0ttttttttttttttt\0";
    int i = 0;
    i = strlen(num);
    Serial.println(i);
    Serial.println(num);
    Serial.println((int)num);
    Serial.println((char *)256);
    read_number(0, num);
    Serial.println();
    
    Serial.print("read: ");
    for (int i=0;i<NUMBER_LENGTH;i++) Serial.println(num[i]);
    for (int i=0;i<NUMBER_LENGTH;i++) num[i] = 'z';
    for (int i=0;i<NUMBER_LENGTH;i++) Serial.println(num[i]);
    Serial.println();
    
    /**/
    Serial.println(is_registered("+38947888888"));
    /**/
    
    /* show memory */
    for (int i=0;i<2048; i++) {
        if (i % 16 == 0) {
            Serial.println();
            if (i<1000) Serial.print(' ');
            if (i<100) Serial.print(' ');
            if (i<10) Serial.print(' ');
            Serial.print(i);
            Serial.print(": ");
        }
        byte* pointer;
        pointer = (byte *)i;
        if (*pointer < 0x10) Serial.print('0');
        Serial.print(*pointer, HEX);
        Serial.print(" ");
    }
    Serial.println();
    /**/
    
    while (1) {}
}

void loop() { }

It's probably because you do

out_num[NUMBER_LENGTH] = 0;

It creates a buffer overflow because you are writing outside of the array (the last index of the array is NUMBER_LENGTH - 1)

Here is a corrected read_number function:

void read_number(int index, char *out_num) {
    int slot_base = index * NUMBER_LENGTH;
   
    for (int i=0; i<NUMBER_LENGTH-1; i++) {
        char data =  extEEPROM.read(slot_base + i);
        out_num[i] = data;
       
    }
    out_num[NUMBER_LENGTH-1] = 0;
}

Thank you for your replies, you’ve greatly helped me in solving the problem.

ToddL1962:
Here is a corrected read_number function:

void read_number(int index, char *out_num) {

int slot_base = index * NUMBER_LENGTH;
 
   for (int i=0; i<NUMBER_LENGTH-1; i++) {
       char data =  extEEPROM.read(slot_base + i);
       out_num[i] = data;
     
   }
   out_num[NUMBER_LENGTH-1] = 0;
}

This did work but clipped the last number. In my case declaring the output to be NUMBER_LENGTH+1
and leaving out_num[NUMBER_LENGTH] = 0; did the trick.
Nonetheless, thanks both of you.

    char read_num[NUMBER_LENGTH];
   
    for (int i=0; i<num_slots; i++) {
        read_number(i, read_num);

This is a bug. Your ‘readNumber()’ function puts a terminating 0 in character ‘NUMBER_LENGTH’ but your array doesn’t have space for it. Try:

    char read_num[NUMBER_LENGTH + 1];

The compiler complains that you are trying to fit 21 characters into a 20-character array:

In function 'void setup()':
65:18: warning: initializer-string for array of chars is too long [-fpermissive]
   char num[20] = "ttt\0ttttttttttttttt\0";
                  ^~~~~~~~~~~~~~~~~~~~~~~~

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.