Reputation: 738
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.
Any idea why it behaves so? The documentation doesn't help in this matter.
EDIT.1: Changed &length
to &data_length
. I manually typed the code instead of copying in SX.
EDIT.2: Code to print out the BYTE array.
Upvotes: 0
Views: 1296
Reputation: 39
Doing memcpy()
from BYTE*
to char*
may lead to wrap around range of char
i.e. -127 to 127 due to BYTE
being unsigned from 0 to 255.
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*
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 i.e. memcpy()
from char*
to 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...
Upvotes: 0
Reputation: 16026
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);
. 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). 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”. The pointer value ([basic.compound]) is unchanged by this conversion.
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.
Your problem must be elsewhere.
Upvotes: 3
Reputation: 4287
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.
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. They're not, even on platforms where the size matches the one is signed while the other one is unsigned.
Upvotes: 1