Сбой memcpy для структуры, содержащей массив char - PullRequest
1 голос
/ 15 октября 2019
struct Frame_t
{
    uint16_t src_id;
    uint16_t dst_id;
    unsigned char num;
    uint8_t is_seq;
    char data[48];
};
typedef struct Frame_t Frame;
char *convert_frame_to_char(Frame *frame)
{
    char *char_buffer = (char *)malloc(64);
    memset(char_buffer,
           0,
           64);
    memcpy(char_buffer,
           frame,
           64);
    return char_buffer;
}

Frame *convert_char_to_frame(char *char_buf)
{
    Frame *frame = (Frame *)malloc(sizeof(Frame));
    memset(frame->data,
           0,
           sizeof(char) * sizeof(frame->data));
    memcpy(frame,
           char_buf,
           sizeof(char) * sizeof(frame));
    return frame;
}

с этими функциями полезности, если я сделаю

            Frame *outgoing_frame = (Frame *)malloc(sizeof(Frame));
//   outgoing_cmd->message  contains "I love you"
            strcpy(outgoing_frame->data, outgoing_cmd->message);
            outgoing_frame->src_id = outgoing_cmd->src_id; // 0
            outgoing_frame->dst_id = outgoing_cmd->dst_id; // 1
            outgoing_frame->num = 100;
            outgoing_frame->is_seq = 1;
            //Convert the message to the outgoing_charbuf
            char *outgoing_charbuf = convert_frame_to_char(outgoing_frame);
            // Convert back
            Frame *test = convert_char_to_frame(outgoing_charbuf);
            // print test->data is "I "

src теста равен 0, dst теста равен 1, данные "I", номер теста d, тест is_seq равен 1.

Итак, почему данные всего 2 символа? Как правильно сделать это без потерь?

Спасибо!

Ответы [ 2 ]

5 голосов
/ 15 октября 2019
memcpy(frame,
       char_buf,
       sizeof(char) * sizeof(frame));

должно быть

memcpy(frame,
       char_buf,
       sizeof(Frame));

size(frame) - размер указателя. Таким образом, вы только копируете size of pointer байтов из массива.

1 голос
/ 15 октября 2019

Это:

memcpy(frame, char_buf, sizeof(char) * sizeof(frame));

не имеет смысла, как указано в комментариях. Умножение размеров здесь не логично.

Поскольку frame является указателем, на мой взгляд, лучше всего использовать sizeof для того, на что указывает указатель, поскольку это то, что происходитcopyied (into):

memcpy(frame, char_buf, sizeof *frame);

Это также слегка «блокирует» количество копируемых байтов до размера буфера назначения, без повторения имени типа, что может быть хорошим.

Также помните, что sizeof не является функцией, скобки нужны только в том случае, если аргумент является именем типа, поскольку они являются частью аргумента (который в данном случае выглядит как приведение).

...