简体   繁体   English

memcpy 是否取决于源指针和目标指针的类型?

[英]Does memcpy depend on the type of the source and destination pointers?

This code,这段代码,

uint32_t length;
BYTE* message;
printf("Inspecting message with length %d and contents: ", length);
for(int i=0;i<length;i++)
    printf("%d ", message[i]);
printf("\n");
....
char* outbuff;
outbuff = (char*) malloc(sizeof(char) * length + sizeof(int));
uint32_t data_length = htonl(length);
memcpy(outbuff, &data_length , sizeof(int));
memcpy(outbuff + sizeof(uint32_t), message, length);

printf("Sending  outbuff over network with length %d and contents: ", length);
for(int i=0;i<length;i++)
    printf("%d ", outbuff[i]);
printf("\n");

doesn't faithfully copy data from message and length to outbuff.不会忠实地将数据从消息和长度复制到输出缓冲区。 But as soon as I change the type of outbuff from char* to BYTE*, it works fine.但是,只要我将输出缓冲区的类型从 char* 更改为 BYTE*,它就可以正常工作。

Any idea why it behaves so?知道为什么它会这样吗? The documentation doesn't help in this matter.文档在这件事上没有帮助。

EDIT.1: Changed &length to &data_length . EDIT.1:将&length更改为&data_length I manually typed the code instead of copying in SX.我手动输入代码而不是在 SX 中复制。

EDIT.2: Code to print out the BYTE array. EDIT.2:打印出 BYTE 数组的代码。

I'm answering the new title question which I just edited in myself;-).我正在回答我刚刚自己编辑的新标题问题;-)。

The answer is a simple No.答案很简单

The link in your question shows that memcpy() is declared as void *memcpy(void *dest, const void *src, size_t n);您问题中的链接显示memcpy()被声明为void *memcpy(void *dest, const void *src, size_t n); . . Both pointer parameters are void pointers.两个指针参数都是空指针。

The standard draft lists conversions of any pointer to void * as a standard conversion (which does not need an explicit cast).标准草案将任何指向void *的指针的转换列为标准转换(不需要显式转换)。 Specifically, it states (emphasis by me):具体来说,它指出(我强调):

A prvalue of type “pointer to cv T”, where T is an object type, can be converted to a prvalue of type “pointer to cv void”. “指向 cv T 的指针”类型的纯右值,其中 T 是 object 类型,可以转换为“指向 cv void 的指针”类型的纯右值。 The pointer value ([basic.compound]) is unchanged by this conversion.此转换未更改指针值 ([basic.compound])。

This means that any object pointer you throw at it will be converted to a numerically identical void pointer before memcpy even sees it, and hence be treated identically.这意味着你扔给它的任何 object 指针都将在 memcpy 看到它之前转换为数字相同的 void 指针,因此被同等对待。

Your problem must be elsewhere.你的问题一定出在其他地方。

Just guessing here but I think you meant to use network byte ordering, hence the data_length attribution, but after it you still put the length into the buffer instead.只是在这里猜测,但我认为您的意思是使用网络字节顺序,因此使用data_length属性,但在此之后您仍然将length放入缓冲区。

Your您的

memcpy(outbuff, &length, sizeof(int));

should have probably read应该读过

memcpy(outbuff, &data_length, sizeof(uint32_t));

Also you seem to be using int and uint32_t interchangeably.此外,您似乎可以互换使用intuint32_t They're not, even on platforms where the size matches the one is signed while the other one is unsigned.它们不是,即使在大小匹配的平台上,一个已签名而另一个未签名。

Doing memcpy() from BYTE* to char* may lead to wrap around range of char ie -127 to 127 due to BYTE being unsigned from 0 to 255.由于BYTE从 0 到 255 无符号,从BYTE*char*执行memcpy()可能会导致环绕char范围,即 -127 到 127。

For example, suppose we have:例如,假设我们有:

BYTE uchArr[] = {12, 129, 250};
BYTE * ptr_uchArr = (BYTE*) malloc (sizeof(BYTE)*3);
memcpy(ptr_uchArr, &uchArr, sizeof(BYTE)*3);
//ptr_uchArr shall be {12, 129, 250} as intended...

And now we want to perform memcpy() from BYTE* to char*现在我们要执行从BYTE*char*memcpy()

char * ptr_chArr = (char*) malloc (sizeof(char)*3);
memcpy(ptr_chArr, ptr_uchArr, sizeof(BYTE)*3);
//ptr_chArr shall be {12, -127, -6} as a result of wrap around...

What if we perform the reverse ie memcpy() from char* to BYTE* :如果我们执行相反的操作,即memcpy()char*BYTE*怎么办:

memcpy(ptr_uchArr, ptr_chArr, sizeof(BYTE)*3);
//ptr_uchArr shall still be {12, 129, 250} as intended again as a result of wrap around...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM