Help please , I need to put the time and a text in a array

I want to keep the 16 last events in my arduino controller, so I make a array like this

char* Eventos[16] ={"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"};

I put this values only to probe the code.

Then I make a routine to show this value all that’s ok
This show this screen

All that’s perfect but when some events occurs I call this routine

EventoNuevo("Protector");   // a text to show the event like light on light off or what else

And this routine make that
move all the previus values to keep the last one and put the time of the events

void EventoNuevo( char* QuePaso )
{
    char TimeandEvent[128];
    char* Hora = Reloj.Time();    

/*his routine is to move the older values ​​at the beginning and put in the last position the last event occurred
*/
    for (int Bucle=1; Bucle<16; Bucle++)
    {
      Eventos[Bucle-1]=Eventos[Bucle];
    }
    strncpy(TimeandEvent, Reloj.Time(), sizeof(TimeandEvent));
    strncat(TimeandEvent, QuePaso, (sizeof(TimeandEvent) - strlen(TimeandEvent)) );
    Eventos[15]=TimeandEvent;
}

But when I see the screen al work fine in the first run, See that

But if another event ocurr I a call the routine at the same way see what happend.
This screen is for 4 events ,
I don’t know why they replace all the same values with the last. Always put the same time, It seems like the routine don’t move this values…

The problem is here

    strncpy(TimeandEvent, Reloj.Time(), sizeof(TimeandEvent));
    strncat(TimeandEvent, QuePaso, (sizeof(TimeandEvent) - strlen(TimeandEvent)) );

This code I find in google to put a text to the time of my Watch
If I don’t use work , but I need the time to the event.
Can any body help me ?

I only need to make something like this

Eventos[15]=Reloj.Time() + QuePaso ; // both are text …
But is not the correct code to C++

for (int Bucle=1; Bucle<16; Bucle++)
    {
      Eventos[Bucle-1]=Eventos[Bucle];
    }

This piece of code will move all the elements of the array, in the way you intended, but it never does anything with the last element of the array.

If you create 4 of these events, then each of those 4 messages needs to have separately allocated memory.

When you declare the char array TimeandEvent[128] in your function, this array is local to the function and will go "out of scope" when the function ends. It should disappear. So, setting the char* Eventos[15] to point to this char array is actually invalid.

But, since the memory which was allocated for that array is not actually being overwritten, it seems to work, but it really shouldn't. You are just being "lucky" that the memory locations that string is in, hasn't been re-used for something else.

When you call that function 4 times, then by coincidence, it keeps using the same memory address for the TimeandEvent array in the second , and subsequent, function calls. It writes the new time into that array. It then shuffles pointer 15 to 14, and writes a new pointer in 15 which happens, by coincidence , to point to the same memory location.

To solve this problem, is not simple. Each time you create a new time and event message, you have to dynamically allocate memory for it. Or create a string object. You then need to keep track of these dynamically allocated char arrays or string objects, and make sure you delete them when the reach the other end of your queue. This is not hard if you know what you are doing, but complicated by the small memory of the arduino. You probably cannot fit 16 x 128 char arrays on the Uno.

Something like this might work.

void EventoNuevo( char* QuePaso )
{
    char* newEvent = new char[48] ;     // allocate a new dynamic array, smaller than what you had
    char* Hora = Reloj.Time();    

/*his routine is to move the older values ​​at the beginning and put in the last position the last event occurred
*/

    delete [] Eventos[0] ;   // delete the dynamically allocated string currently at array position 0

    for (int Bucle=1; Bucle<16; Bucle++)
    {
      Eventos[Bucle-1]=Eventos[Bucle];
    }
    strncpy(newEvent, Reloj.Time(), 48 );
    strncat(newEvent, QuePaso, ( 48 - strlen(newEvent)) );
    Eventos[15]=newEvent ;
}

This code will work, but there are other issues you would need to change also. The 16 dummy strings that you originally filled your array with, are not dynamically allocated arrays. So, when you get your first real event, and you try to delete the 0 element in the array before you shuffle all the other strings down from 15, you don’t have a dynamically allocated string to delete. To solve this problem, you also need to make those 16 initial strings to be dynamically allocated, also.

char* Eventos[16] ;                // this array of pointers is a global variable

for ( int i=0 ; i<16 ; i++ )
{
  Eventos[i] = new char[4] ;
  sprintf( Eventos[i],"%d",(i+1));
}

Something like that, should work.

Your array is an array of pointers to strings.

Initially, you set each element of that array to a separate chunk of memory that the compiler sets aside for each string.

When the code runs the first time, element 15 is set to point at a chunk of memory named 'TimeandEvent'. The second time the loop runs, both element 14 and element 15 point to that same chunk of memory. So whatever you put in there becomes what appears at both array indexes.

Instead of having an array of 15 pointers to strings, try setting aside 15 chunks of memory that each will be long enough for a string. If the longest string is 20 characters, you will need each element to be 21 characters to accommodate the terminating NUL.

char Eventos[16][21] ={"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"};