memcpy with startIndex?

2020-05-19 06:49发布

问题:

I wish to copy content of specific length from one buffer to another from a specific starting point. I checked memcpy() but it takes only the length of content to be copied while I want to specify the starting index too.

Is there any function which can do this or is there any good approach to do it with the existing memcpy function?

回答1:

I always prefer the syntax

memcpy( &dst[dstIdx], &src[srcIdx], numElementsToCopy * sizeof( Element ) );


回答2:

Just add the offset you want to the address of the buffer.

char abuff[100], bbuff[100];
....
memcpy( bbuff, abuff + 5, 10 );

This copies 10 bytes starting at abuff[5] to bbuff.



回答3:

Just add the offset to the addresses. For example, if you wanted to copy the buffer starting with the Nth byte:

memcpy( destination, source + N, sourceLen - N );

This will copy to the destination. If you also want to offset the destination - add the offset to both:

memcpy( destination + N, source + N, sourceLen - N );


回答4:

An index is not required because you can simply update the source pointer by the specified number of bytes. The following wrapper should do the trick

void* memcpy_index(void *s1, const void *s2, size_t index, size_t n) {
  s2 = ((char*)s2)+index;
  return memcpy(s1, s2,n);
}


回答5:

Simply increase your pointer to your start index.

Example

const unsigned char * src = reinterpret_cast<const unsigned char*>(your source);
unsigned char * dest = reinterpret_cast<unsigned char *>(your dest);
memcpy(dest, src + offset, len);

What about using STL collections to avoid memory access errors?



回答6:

This site needs a way to allow anonymous followups in addition to anonymous answers.

Why, more than once, do I see this insane assertion that an "index" must be in units of 1 byte? It's the complete opposite of convention. An "index" is usually symbolic, a measure whose physical byte offset is determined by the size of the element in the array (or vector, which may not even have the physical layout of an array, but then memcpy() is irrelevant too of course).

So, the 5th element in an array has "index" 5, but:

  • If the array is type char, then the byte offset of that "index" is 5.
  • If the array is type short (on x86), then the byte offset of that "index" is 10.
  • If the array is type int (on x86), then the byte offset of that "index" is 20.
  • If the array is type of some large 48-byte object, then the byte offset of that "index" is 240.

Which way is the correct way to access that specific element is a side point. The important part is that you understand the difference, choose one, and make the code correct.


On the meaning of words, I would much rather read:

 void* memcpy_offset(void *s1, const void *s2, size_t offset, size_t n);

than:

 void* memcpy_index(void *s1, const void *s2, size_t index, size_t n);

I find the idea that a completely generic void * could have an "index" to be misleading. (While we're here, "dest" and "source" or "in" and "out" would be much less ambiguous than "s1" and "s2". Code doesn't need as many comments when you pick self-explanatory variable names.)



回答7:

Simply add the index to the address of the buffer, and pass it to memcpy() as the source parameter, e.g. copy from 3rd item of buffer b

char a[10], b[20];
::memcpy(a,b+2,10);

Also take into account the type of items in the buffer, length (3rd) parameter of memcpy() is in bytes, so to copy 4 ints you shall put 4*sizeof(int) - which will probably be 16 (on a 32 bit system. But the type does not matter for the start address, because of pointer arithmetics:

int a[10], b[10];
::memcpy( a+2, b, 2*sizeof(int) );
// a+2 will be address of 3rd item in buffer a
// not address of 1st item + 2 bytes


回答8:

You could have a function like below.

template<typename T>
T* memcopy_index(T* dst,T* src,unsigned int index, unsigned int element_count)
{
    return (T*)memcpy(dst,src + index, element_count * sizeof(T));
}

It can be used as below:

int src[]={0,1,2,3,4,5,6};
int dst[15];

memcopy_index(dst,src,2,5);    //copy 5 elements from index 2

You have to make sure that destination buffer has enough room to copy the elements.



回答9:

If you're using c++, it is probably better to use std::copy() instead of memcpy(). std::copy can take pointers just as easily as iterators.

e.g.

int src[20];
int dst[15];

// Copy last 10 elements of src[] to first 10 elements of dst[]
std::copy( src+10, src+20, dst );

As with memcpy(), it's your responsibility to make sure the pointers are valid.

NOTE. If your usage is performance critical you may find a memcpy() as detailed in the other answers quicker, but probably not by much.



标签: c++ memcpy