Memcpy: добавление смещения int? - PullRequest
3 голосов
/ 25 февраля 2012

Я просматривал код C ++ и наткнулся на эту функцию memcpy.Я понимаю, что делает memcpy, но они добавляют int к источнику.Я попытался найти исходный код memcpy, но не могу понять, что на самом деле делает добавление к функции memcpy.

memcpy(Destination, SourceData + intSize, SourceDataSize);

Другими словами, я хочу знать, что делает SourceData + intSize.(Я пытаюсь преобразовать это в Java.)

РЕДАКТИРОВАТЬ:

Итак, вот моя попытка сделать функцию memcpy в Java с использованием цикла for ...

for(int i = 0 ; i < SourceDataSize ; i ++ ) {
      Destination[i] = SourceData[i + 0x100];
}

Ответы [ 6 ]

10 голосов
/ 25 февраля 2012

Это то же самое, что и:

memcpy(&Destination[0], &SourceData[intSize], SourceDataSize);
1 голос
/ 25 февраля 2012

SourceData + intSize пропускает intSize * sizeof (тип данных источника) байтов в начале SourceData. Может быть, там хранится SourceDataSize или что-то в этом роде.

1 голос
/ 25 февраля 2012

Это базовая арифметика указателей.SourceData указывает на некоторый тип данных, и добавление n к нему увеличивает адрес, на который он указывает, на n * sizeof (* SourceData).

Например, если SourceData определен как:

uint32_t *SourceData;

и

sizeof(uint32_t) == 4

, затем добавление 2 к SourceData увеличит адрес, который он содержит, на 8.

В качестве отступления, если SourceData определен как массив, то добавление n к нему иногдатак же, как доступ к n-му элементу массива.Это достаточно легко увидеть при n == 0;когда n == 1, легко увидеть, что вы будете обращаться к адресу памяти размером байтов sizeof (* SourceData) после начала массива.

1 голос
/ 25 февраля 2012

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

Количество изменений адреса будет зависеть от типа SourceData.

(см. http://www.learncpp.com/cpp-tutorial/68-pointers-arrays-and-pointer-arithmetic/)

Возможно, пытается скопировать часть массива SourceData, начиная со смещения intSize и длины SourceDataSize / sizeof (* SourceData).

EDIT

Так, например, если массив состоит из целых чисел размером 4 байта, то эквивалентный код Java будет выглядеть следующим образом:

for(int i = 0 ; i < SourceDataSize/4 ; i ++ ) {
  Destination[i] = SourceData[i + intSize];
}
0 голосов
/ 28 февраля 2012

Что касается этого в Java:

Ваша петля

for(int i = 0 ; i < SourceDataSize ; i ++ ) {
      Destination[i] = SourceData[i + 0x100];
}

всегда начнет копировать данные из 0x100 элементов в SourceData; это может быть нежелательным поведением. (Например, когда i=0, Destination[0] = SourceData[0 + 0x100]; и т. Д.) Это было бы то, что вы хотели, если вы никогда не хотели копировать SourceData[0]..SourceData[0xFF], но учтите, что жесткое кодирование предотвращает его замену для замены. тетср.

Причина, по которой значение intSize указано в исходном коде, вероятна потому, что первые элементы intSize не являются частью «фактических» данных, и эти байты каким-то образом используются для учета (как запись того, что общий размер буфера есть). memcpy сам не «видит» смещение; он знает только указатель, с которого он начинается. SourceData + intSize создает указатель, который указывает intSize байт за SourceData.

Но, , что более важно , то, что вы делаете, вероятно, будет чрезвычайно медленным . memcpy - это очень сильно оптимизированная функция, которая отображается на тщательно настроенную сборку на большинстве архитектур, и замена ее простой итерацией по циклам за байтом существенно повлияет на характеристики производительности кода. Хотя то, что вы делаете, уместно, если вы пытаетесь понять, как работают memcpy и указатели , учтите, что если вы пытаетесь перенести существующий код на Java для реального использования, вы, вероятно, захотите использовать морально эквивалентную Java функция как java.util.Arrays.copyOf.

0 голосов
/ 25 февраля 2012

Ближайший эквивалент memcpy в Java, который вы, вероятно, получите, равен System.arraycopy, поскольку в действительности Java не имеет указателей в том же смысле.

...