Подтвердить что ты не робот

Memcpy с startIndex?

Я хочу скопировать содержимое определенной длины из одного буфера в другой с конкретной отправной точки. Я проверил memcpy(), но для копирования требуется только длина содержимого, в то время как я хочу также указать начальный индекс.

Есть ли какая-либо функция, которая может это сделать или есть ли хороший подход к ней с существующей функцией memcpy?

4b9b3361

Ответ 1

Я всегда предпочитаю синтаксис

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

Ответ 2

Просто добавьте смещение, которое вы хотите к адресу буфера.

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

Это копирует 10 байт, начиная с abuff [5], bbuff.

Ответ 3

Просто добавьте смещение к адресам. Например, если вы хотите скопировать буфер, начиная с N-го байта:

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

Это скопируется в destination. Если вы также хотите компенсировать назначение - добавьте смещение к обоим:

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

Ответ 4

Индекс не требуется, потому что вы можете просто обновить указатель источника на указанное количество байтов. Следующая оболочка должна сделать трюк

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

Ответ 5

Просто добавьте указатель к индексу начала.

Пример

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);

Как использовать коллекции STL, чтобы избежать ошибок доступа к памяти?

Ответ 6

Этот сайт нуждается в способе анонимного наблюдения в дополнение к анонимным ответам.

Почему я не раз вижу это безумное утверждение о том, что "индекс" должен быть в единицах 1 байт? Это полная противоположность конвенции. "Индекс" обычно является символическим, мера, физическое смещение байта которого определяется размером элемента в массиве (или вектором, который может даже не иметь физического расположения массива, но тогда memcpy() также не имеет значения Конечно).

Итак, 5-й элемент в массиве имеет "индекс" 5, но:

  • Если массив имеет тип char, то смещение байта этого "индекса" равно 5.
  • Если массив имеет тип short (на x86), тогда смещение байта этого "индекса" равно 10.
  • Если массив имеет тип int (на x86), тогда смещение байта этого "индекса" равно 20.
  • Если массив является типом некоторого большого 48-байтового объекта, тогда смещение байта этого "индекса" равно 240.

Какой способ является правильным способом доступа к этому конкретному элементу, является боковой точкой. Важная часть состоит в том, что вы понимаете разницу, выбираете ее и делаете код правильной.


По смыслу слов я бы скорее прочитал:

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

чем:

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

Я нахожу идею, что вполне общий void * может иметь "индекс" , который вводит в заблуждение. (Хотя мы здесь, "dest" и "source" или "in" и "out" были бы гораздо менее двусмысленными, чем "s1" и "s2". Коду не нужно столько комментариев, когда вы выбираете самоочевидные имена переменных.)

Ответ 7

Просто добавьте индекс в адрес буфера и передайте его в memcpy() в качестве исходного параметра, например. копия из третьего элемента буфера b

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

Также учитывайте тип элементов в буфере, длина (третий) параметр memcpy() находится в байтах, поэтому, чтобы скопировать 4 интервала, вы должны поместить 4 * sizeof (int), который, вероятно, будет 16 (вкл. 32-разрядная система, но тип не имеет значения для начального адреса из-за арифметики указателя:

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

У вас может быть функция, как показано ниже.

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));
}

Его можно использовать, как показано ниже:

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

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

Вы должны убедиться, что в буфере назначения достаточно места для копирования элементов.

Ответ 9

Если вы используете С++, вероятно, лучше использовать std:: copy() вместо memcpy(). std:: copy может принимать указатели так же легко, как итераторы.

например.

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 );

Как и в memcpy(), ваша ответственность - убедиться, что указатели действительны.

Примечание. Если ваше использование критично для производительности, вы можете найти memcpy(), как указано в других ответах быстрее, но, вероятно, не намного.