1

I'm struggling with this syntax: I have a few structs of arrays:

struct Msg {
    uint8_t Data[DATA_SIZE];
};

struct Msg Msg_Buff[NUM_MESSAGES], Temp_Buff[NUM_MESSAGES];

and want to copy one array from one struct to another.

This:

*Temp_Buff[Other_Indx].Data = *Msg_Buff[This_Indx].Data;

copies ONLY the first element of the array, not the whole array. What am I doing wrong?

nobby
  • 373
  • 1
  • 3
  • 15
  • `memcpy(Temp_Buff[Other_Index].Data,Msg_Buff[This_Index].Data,sizeof(Msg.Data));` – Irelia May 08 '23 at 21:06
  • 4
    You can't assign to arrays, whether they're normal variables or struct members. – Barmar May 08 '23 at 21:08
  • 2
    You _can_ copy whole `struct` with an assignment: `Temp_Buff[Other_Indx] = Msg_Buff[This_Indx];` – Craig Estey May 08 '23 at 21:08
  • Is `Data` really the only member of the struct, or is this simplified from the real struct definition? – Barmar May 08 '23 at 21:09
  • The `*` with zero offset is the equivalent of `Temp_Buff[Other_Indx].Data[0] = Msg_Buff[This_Indx].Data[0];`, which explains why only the first element is being copied – yano May 08 '23 at 21:09
  • I suggest to rephrase the title like this: "How to copy a member of a strruct that is an array into another strruct?" – Amessihel May 08 '23 at 22:30

2 Answers2

6

Largely for historical reasons, in C arrays cannot be assigned.

If the array is the only member in the structure, you can simply assign the structure instead of the array: Temp_Buff[Other_Indx] = Msg_Buff[This_Indx];.

Otherwise, copy the entire array: memcpy(Temp_Buff[Other_Indx].Data, Msg_Buff[This_Indx].Data, sizeof Temp_Buff[Other_Indx].Data);. The memcpy routine is declared in <string.h>.

Note this use of sizeof relies on its operand, Temp_Buff[Other_Indx].Data, being an actual array of known size. If it is a pointer, you need to provide the size in some other way, such as NumberOfElements * sizeof *Temp_Buff[Other_Indx].Data.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Nice answer, upvoted. Could you explain what do you mean by "historical reasons"? – Amessihel May 08 '23 at 21:22
  • Follow up: if I want to copy MULTIPLE arrays, but not ALL, from one to another, I need to iterate with a memcpy for each iteration? – nobby May 08 '23 at 21:27
5

You need to use memcpy for that if you want to copy only one member.

#define DATA_SIZE 100
#define NUM_MESSAGES 200

struct Msg {
    uint8_t Data[DATA_SIZE];
};

struct Msg Msg_Buff[NUM_MESSAGES], Temp_Buff[NUM_MESSAGES];


void copyDataAtIndex(size_t index)
{
    memcpy(Temp_Buff[index].Data, Msg_Buff[index].Data, sizeof(Temp_Buff[index].Data));
}

If you want to copy the whole struct - simply assign:

void copyStructAtIndex(size_t index)
{
    Temp_Buff[index] = Msg_Buff[index];
}
0___________
  • 60,014
  • 4
  • 34
  • 74