简体   繁体   中英

memcpy start index really needed?

The question is when we are copying any Byte array using memcpy() , shall we explicitly declare the starting (0 th) index for the destination buffer or simple mentioning it would suffice. Let me show the examples what I'm talking about. Provided that we are trying to copy source buffer to starting of the destination buffer.

BYTE *pucInputData; // we have some data here
BYTE ucOutputData[20] = {0};

Code 1

memcpy((void*)&ucOutputData, (void*)pucInputData, 20);

Code 2

memcpy((void*)&ucOutputData[0], (void*)pucInputData, 20);

In your case, considering this a C code snippet, and ucOutputData is an array

  • memcpy(ucOutputData, pucInputData, 20);
  • memcpy(&ucOutputData[0], pucInputData, 20);

both are same and can be used Interchangeably. The name of the array essentially gives you the address of the first element in the array.

Now, as per the very useful discussion in below comments, it is worthy to mention, that

memcpy(&ucOutputData, pucInputData, 20);

will also do the job here, but there is a fundamental difference between the usage of array name and address of array name . Considering the example in the question, for a definition like BYTE ucOutputData[20] ,

  • ucOutputData points to the address of the first element of an array of 20 BYTE s.
  • &ucOutputData is a pointer to an array of 20 BYTE s.

So, they are of different type and C respects the type of the variable. Hence, to avoid any possible misuse and misconception, the recommended and safe way to use this is either of the the first two expressions.

FWIW, the cast(s) here is(are) really not needed. Any pointer type can be implicitly ansd safely be converted to void * in C.

Since an expression &array[0] is the same as array , and because any pointer can be implicitly converted to void* , you should do this instead:

memcpy(ucOutputData, pucInputData, 20);

Moreover, since you are writing over the entire ucOutputData , you do not need to zero out its content, so it's OK to drop the initializer:

BYTE ucOutputData[20]; // no "= {0}" part

No, both of your examples are sub-optimal.

Remember that all data pointers in C convert to/from void * (which is the type of the first argument to memcpy() ) without loss of information and that no cast is necessary to do so.

Also remember that the name of an array evaluates to the address of the first element in many contexts, such as here.

Also remember to use sizeof when you can, never introduce a literal constant when you don't have to.

So, the copy should just be:

memcpy(ucOutputData, pucInputData, sizeof ucOutputData);

Note that we use sizeof without parentheses, it's not a function. Also we use it on the destination buffer, which seems the safer choice.

A native array can decay to a pointer without conversion, so in the snippet below, the three assignments to p all result in the same value; p will point to the beginning of the array. No explicit cast is needed because casting to void* is implicit.

typedef char BYTE;
BYTE ucOutputData[20] = {0};

void *p = &ucOutputData;
p = ucOutputData;
p = &ucOutputData[0];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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