我在使用memcpy从缓冲区中提取数据时遇到了一些困难。
首先,我将一些变量记忆到缓冲区中:
int l1_connect(const char* hostname, int port) {
// Variables to be stored in the buffer
char *msg = "Hi, I'm a message"; // strlen(msg) == 17
uint16_t sender_id = htons(1); // sizeof(sender_id) == 2
uint16_t packet_size = htons(sizeof(packet_size)+sizeof(sender_id)+strlen(msg)); // sizeof(packet_size) == 2
// Checking values
printf("l1_connect():\nsender_id: %d, packet_size: %d\n\n", ntohs(sender_id), ntohs(packet_size));
// sender_id == 1, packet_size == 21
// The buffer
char buf[100];
// Copying everything
memcpy(&buf, &sender_id, sizeof(sender_id));
memcpy(&buf+sizeof(sender_id), &packet_size, sizeof(packet_size));
memcpy(&buf+sizeof(sender_id)+sizeof(packet_size), &msg, strlen(msg));
// Passing buf to another function
int bytes_sent = l1_send(1, buf, sizeof(buf));
}
然后我尝试提取该数据(在通过UDP套接字发送之前检查):
int l1_send( int device, const char* buf, int length ) {
// Variables in which to store extracted data
uint16_t id = 0;
uint16_t size = 0;
char msg[50];
memcpy(&id, &buf, sizeof(id));
memcpy(&size, &buf+sizeof(id), sizeof(size));
int remaining = ntohs(size) - (sizeof(id) + sizeof(size));
printf("l1_send():\nremaining: %d\n", remaining); // -37041
// memcpy-ing with correct(?) offset
memcpy(&msg, &buf+sizeof(id)+sizeof(size), 50);
msg[49] = '\0';
printf("id: %d\n", ntohs(id)); // 8372
printf("size: %d\n", ntohs(size)); // 37045
printf("msg: %s\n", msg); // ��$_�
return 0; // For now
}
正如您所看到的,这些值并不是我所期待的。谁能告诉我我做错了什么?
答案 0 :(得分:6)
您的指针数学不正确。您正在使用&buf
,您应该使用buf
。如果这不能解释什么是错的,那么我无能为力:
#include <stdio.h>
int main(int argc, char **argv)
{
char buff[100];
printf("buff : %p\nbuff+10 : %p\n&buff+10 : %p\n", buff, buff+10, &buff+10);
return 0;
}
输出(显然因平台而异)
buff : 0xbf87a8bc
buff+10 : 0xbf87a8c6
&buff+10 : 0xbf87aca4
See it live。你正在做的数学是按类型递增,&buf
是指向100 char
s的数组的指针;不是一个简单的char
地址。因此,&buff + 10
(在我的样本中)说“从我现在的位置给我第10个100个字符阵列。”后续写入因此调用未定义的行为。
Valgrind是你的好友,顺便说一下。它会在心跳中发现这一点。
<强>更新强>
在我到这儿的时候,也可以填写整个开局。这在l1_send
:
memcpy(&id, &buf, sizeof(id));
// this------^
以及您在该功能中使用的其他后续区域。您将获取参数指针的地址,而不是其中的值。我相信你也需要buf
。
答案 1 :(得分:3)
试试这个:
memcpy(buf, &sender_id, sizeof(sender_id));
memcpy(buf + sizeof(sender_id), &packet_size, sizeof(packet_size));
memcpy(buf + sizeof(sender_id) + sizeof(packet_size), msg, strlen(msg));
为了帮助您了解代码的错误,您可以阅读this。