c - 使用指针作为结构成员将结构序列化为字节数组

标签 c

我正在尝试将一个字节数组复制到我的结构,然后再次将我的结构序列化为一个字节数组。

但是,在我序列化我的结构数组之后,我无法再次获取我的数据值(0x12、0x34、0x56),而是我得到了一些垃圾数据。

这里有什么问题吗?

#pragma pack(push, 1)
typedef struct {
    uint8_t length;
    uint8_t *data;
} Tx_Packet;
#pragma pack(pop)

static void create_tx_packet(uint8_t *packet, uint8_t *src, int length);

int main(void)
{
    uint8_t packet[32];
    uint8_t data[] = { 0x12, 0x34, 0x56 };

    create_tx_packet(packet, data, 3);

    //i check using debugger, i cant get the data value correctly
    //but i could get length value correctly


    return 0;
}

static void create_tx_packet(uint8_t *packet, uint8_t *src, int length)
{
    Tx_Packet *tx_packet = malloc(sizeof(*tx_packet ));

    tx_packet->length = length;
    tx_packet->data = (uint8_t *)malloc(length);
    memcpy(tx_packet->data, src, length);

    memcpy(packet, tx_packet, sizeof(*tx_packet));
}

最佳答案

现在,您的 create_tx_packet() 函数将函数中创建的 Tx_Packet 结构复制到 uint8_t 数组。该结构包含数据的长度和一个指针,但不包含数据本身。实际上根本没有必要将结构用作中间步骤,特别是对于这样一个简单的数据包,因此您可以改为:

static void create_tx_packet(uint8_t *packet, uint8_t *src, int length)
{
  *packet = length; /* set (first) uint8_t pointed to by packet to the
                       length */
  memcpy(packet + 1, src, length);  /* copy length bytes from src to
                                       the 2nd and subsequent bytes of
                                       packet */
}

您仍然需要确保 packet 指向足够的空间(至少 length + 1 字节)用于所有内容(它确实如此)。由于上面的版本没有动态分配任何东西,它还修复了你原来的内存泄漏(它应该在退出之前释放 tx_packet->datatx_packet)。

--

如果您确实想使用一个结构,您可以(因为数据在末尾)更改您的结构以使用数组而不是 data 的指针——然后在结构的大小可用于数据,并通过结构中的 data 数组访问。该结构可能是:

typedef struct {
  uint8_t length;
  uint8_t data[];
} Tx_Packet;

函数变为(如果使用临时结构):

static void create_tx_packet(uint8_t *packet, uint8_t *src, int length)
{
  /* allocate the temporary struct, with extra space at the end for the
     data */
  Tx_Packet *tx_packet = malloc(sizeof(Tx_Packet)+length);

  /* fill the struct (set length, copy data from src) */
  tx_packet->length = length;
  memcpy(tx_packet->data, src, length);

  /* copy the struct and following data to the output array */
  memcpy(packet, tx_packet, sizeof(Tx_Packet) + length);

  /* and remember to free our temporary struct/data */
  free(tx_packet);
}

不过,除了分配一个临时结构,您还可以使用结构指针直接访问 packet 中的字节数组,从而避免额外的内存分配:

static void create_tx_packet(uint8_t *packet, uint8_t *src, int length)
{
  /* Set a Tx_Packet pointer to point at the output array */
  Tx_Packet *tx_packet = (Tx_Packet *)packet;

  /* Fill out the struct as before, but this time directly into the
     output array so we don't need to allocate and copy so much */
  tx_packet->length = length;
  memcpy(tx_packet->data, src, length);
}

关于c - 使用指针作为结构成员将结构序列化为字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30880968/

相关文章:

c - 在 C 中,如何从函数内部初始化指向指针的指针?

c - ANSI C YACC 语法中的歧义

c - K&R 中的指针加法

c - 如何使用相同的代码复制在文件中创建的完全相同的结构?

c++ - OpenCV如何在二进制图像中找到连接组件的列表

c - 尽管声明了,但 while 循环中还是 "Undeclared: first use in function error"

c - 在 C 中构建时断言表达式的方法

c - 双向链表C实现运行时错误

c - 如何修复段错误(核心转储)错误

c - 加载二进制文件 - realloc() : invalid next size