【发布时间】:2013-06-28 19:28:58
【问题描述】:
我有一个如下所示的结构:
struct dgm_network_pkt {
char responder[INET_ADDRSTRLEN];
int num;
char **neighbors;
};
num 字段跟踪已分配并由neighbors 指向的字符数组。
现在我想构造一个包含标头和结构的数据包,并发送一个包含该数据包的 UDP 数据包。为了做到这一点,我需要做很多指针运算,以及对 sizeof() 的大量调用。例如,如果我的头是enum header hdr;,我的缓冲区是char *buf;,我的结构实例是struct mystruct stc;,我需要执行以下操作(sn-p):
buf = malloc(sizeof(stc.num * SIZEOF_EACH_ARRAY) + sizeof(hdr) + sizeof(stc.responder) + sizeof(int));
memcpy(buf, &hdr, sizeof(hdr)); /* Copy over header */
memcpy(buf + sizeof(hdr), &stc.responder, sizeof(stc.responder)); /* Copy 'responder' field */
memcpy(buf + dizeof(hdr) + sizeof(stc.responder), &stc.num, sizeof(int)); /* Copy num field */
然后循环复制neighbors 指向的字符数组,再次使用相同的参数多次调用sizeof()。
如果您愿意看,这里是我用来完成所有这些的功能以供参考,但没有必要回答我的问题,并且可能会增加混乱(增加了间接性)。
int dismesh_compose_net_pkt(struct dgm_network_pkt *dismesh_sta, char **buf)
{
int i;
int pkt_size;
enum dgm_header dgm_hdr;
pkt_size = dismesh_sta->num * DISMESH_ETH_ADDR_STR + sizeof(dgm_hdr)
+ sizeof(dismesh_sta->responder) + sizeof(int);
dgm_hdr = NETWORK_STATUS_RESP;
if ((*buf = malloc(pkt_size)) == NULL)
return -1;
memcpy(*buf, &dgm_hdr, sizeof(dgm_hdr));
memcpy(*buf + sizeof(dgm_hdr), &dismesh_sta->responder, sizeof(dismesh_sta->responder));
memcpy(*buf + sizeof(dgm_hdr) + sizeof(dismesh_sta->responder), &dismesh_sta->num, sizeof(int));
/* Copy contents of neighbors to buffer */
for (i = 0; i < dismesh_sta->num; i++) {
memcpy(*buf + sizeof(dgm_hdr) + sizeof(dismesh_sta->responder) + sizeof(int) + i * DISMESH_ETH_ADDR_STR,
*(dismesh_sta->neighbors + i), DISMESH_ETH_ADDR_STR);
DGM_LOG("Packed up neighbor %d\n", i);
}
return pkt_size;
}
这里是:
我注意到我反复使用相同的参数调用sizeof():将结构的内容复制到缓冲区,每个元素的大小等等。更好的方法来做到这一点?我在想我可以在我的头文件中有一些#defines,比如说,我可以在其中执行#define OFFSET_RESPONDER sizeof(hdr)、#define OFFSET_NUM OFFSET_RESPONDER + sizeof(mystruct.responder) 和#define SIZE_HEADER sizeof(dgm_header) 等。如果保持原样,我会注意到显着的性能损失吗?编译器(在我的情况下是 GCC)是否对此进行了优化?你认为#defines 会降低可读性吗?清理此代码的最佳方法是什么?
【问题讨论】:
-
sizeof没有性能问题,它是编译时评估(C99 的 VLA 除外) -
sizeof()不能被“调用”——它不是一个函数。这是一个关键字。 -
好吧,让我感到尴尬。在问一个答案如此明显的问题之前,我可能应该做更多的功课=/
标签: c gcc memory-management