c - 为什么将数组中的 a 转换为指针会破坏我的数据?

标签 c gcc struct

我的一个 friend 前几天在 Facebook 上发布了这个问题,但我终究无法弄明白。他正在使用 cubesat 协议(protocol)编写客户端和服务器。出于某种原因,当他将协议(protocol)结构的数据成员转换为指针时,他的数据似乎被破坏了。

客户端代码片段:

uint32_t data[3] = { 1234U, 5678U, 9101U };
memcpy(packet->data32, data, sizeof(data));
packet->length = sizeof(data);
csp_send(connection, packet, 1000);

服务器代码片段:

uint32_t *data = (uint32_t *)(packet->data32);
printf("Packet received on %i: %u\r\n", PORT, data[0]);
printf("Packet received on %i: %u\r\n", PORT, data[1]);
printf("Packet received on %i: %u\r\n", PORT, data[2]);
printf("Packet received on %i: %u, %u, %u\r\n", PORT, data[0], data[1], data[2]);

此代码产生的输出:

Packet received on 15: 2182284498
Packet received on 15: 5678
Packet received on 15: 9101
Packet received on 15: 80904723, 372113408, 596443136

输出这段代码的普通读者所期望的:

Packet received on 15: 1234
Packet received on 15: 5678
Packet received on 15: 9101
Packet received on 15: 1234, 5678, 9101

经过一些摆弄后,他告诉我,如果他不将结构的 data32 成员转换为 uint32_t*,他会得到正确的输出。

根据我自己的研究,packetcsp_packet_t 类型,其定义为:

typedef struct __attribute__((__packed__)) {
        uint8_t padding[CSP_PADDING_BYTES];     // Interface dependent padding
        uint16_t length;                        // Length field must be just before CSP ID
        csp_id_t id;                            // CSP id must be just before data
        union {
                uint8_t data[0];                // This just points to the rest of the buffer, without a size indication.
                uint16_t data16[0];             // The data 16 and 32 types makes it easy to reference an integer (properly aligned)
                uint32_t data32[0];             // - without the compiler warning about strict aliasing rules.
        };
} csp_packet_t;

完整的头文件是here .

这是 GNU C,所以 zero-length arrays are allowed .

我不知道两边架构的字长或字节顺序。

所以,简单地说 - 这里发生了什么?为什么 Actor 很重要?

最佳答案

21822844980x821304D2,其中0x04d21234,其余可能是数据包。更多,不知道 csp_send 和相应的接收器看起来如何(即:显示更多代码)是不可能知道的。

而这一行:memcpy(packet->data32, data, sizeof(data)); 实际上是缓冲区溢出错误...因为你没有为 packet 分配足够的字节->data32

关于c - 为什么将数组中的 a 转换为指针会破坏我的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22683117/

相关文章:

c++ - Ubuntu 13.10 中的 GCC iostream fstream 错误

c - 返回结构并保存在不同 .c 文件中的结构变量中

c - 指针和数组的区别

c - 我的函数中的格式代码

无法理解此代码堆栈存储函数调用 c 的输出

windows - 增加 Windows (GCC) 上的堆栈大小

c++ - 如何在Arduino-ESP8266上从C/C++中的字符串解析time_t?

c - gcc: 错误: 无法识别的命令行选项 ‘-1m’

c - 尝试声明在 C 中使用 typedef 定义的结构时出错

c++ - 如何将结构添加到另一个类的 vector 中?