【发布时间】:2014-11-05 03:01:39
【问题描述】:
给定下面的简单代码,其中 process_payload 被赋予了一个指向数据包有效负载部分的指针,你如何访问标题部分?理想情况下,调用者应该从头开始简单地给出一个指向完整数据包的指针,但在某些情况下,您没有消息的开头,需要向后工作以获取标头信息。我猜这个问题变成了对遍历一个结构体的内存布局的理解。
使用 sizeof 操作将标头计算为 8 个字节。我假设 Visual C++ 编译器在标题中添加了 3 个字节的填充。 在做 ptr arith (pptr->payload - pptr) 时,pptr 和 pptr->payload 的区别是十进制 80(不知道为什么这个值??)。设置 ptr = (struct Packet*)(payload - 80) 有效,但似乎更像是一种黑客行为。我不太明白为什么减去 sizeof(struct header) 不起作用。
感谢您提供的任何帮助。
struct Header
{
unsigned char id;
unsigned int size;
};
struct Packet
{
struct Header header;
unsigned char* payload;
};
void process_payload(unsigned char* payload);
int main()
{
struct Packet* pptr = (struct Packet*)malloc(sizeof(struct Packet));
pptr->payload = (unsigned char*)malloc(sizeof(unsigned char)*10);
process_payload(pptr->payload);
return 1;
}
// Function needs to work backwards to get to header info.
void process_payload(unsigned char* payload)
{
// If ptr is correctly setup, it will be able to access all the fields
// visible in struct Packet and not simply payload part.
struct Packet* ptr;
// This does not work when intuitively it should?
ptr = (struct Packet*)(payload - sizeof(struct Header));
}
【问题讨论】:
-
检查(非标准)
container_of宏,可以看到here -
pptrinmain()在这段代码中毫无意义。在我看来,您正在尝试(但没有成功)为实际有效负载制作 flexible array member。 -
正如 WhozCraig 所说,您一定在尝试做某事:我看不出不直接将
struct Packet *传递给process_payload()的意义 -
你可能想在 malloc 之后初始化你的结构或使用 calloc,在你的 sn-p 中它们未初始化。