【发布时间】:2018-04-19 19:43:56
【问题描述】:
我有一个缓冲区,想将其转换为指向结构的指针:
#include <stdint.h>
#include <stdio.h>
struct __attribute__((packed)) req {
uint8_t a;
uint16_t b;
uint8_t *c;
};
void f(uint8_t *Buf)
{
struct req *r = (struct req *)Buf;
printf("a: %02x\n", r->a);
printf("b: %04x\n", r->b);
printf("c: %02x\n", r->c[0]);
}
int main()
{
uint8_t buf[] = {0x01, 0x02, 0x03, 0x04 };
f(buf);
return 0;
}
这个例子不起作用,因为第 4 个字节不是地址,而是实际数据。我可以通过手动设置指针来“解决”这个问题:
r->c = &Buf[3];
有没有办法通过演员表做到这一点?
【问题讨论】:
-
我不知道指针是单字节的任何硬件,所以对于初学者来说,缓冲区太小了。并且使指针指向自身并不能解决任何问题。它更像是断腿上的创可贴。您真正想在这里做什么?
-
如果你想在结构体中添加一个数组,也许你的意思是
uint8_t c[1];? -
不,这是未定义的行为。通过分配给
r->c,您既破坏了您试图指向的缓冲区内容,又写入了数组buf的末尾。在f,你可以做struct rec r;r.a = Buf[0];r.b = Buf[1] | (Buf[2] << 8); /* assuming little-endian */r.c = &Buf[3];。 -
除了别人说的,通过不兼容的struct成员访问字节数组是一种严格的别名冲突,也是未定义的行为。不要那样做。
-
你期望什么输出?