Как memset () памяти для определенного шаблона вместо одного байта? - PullRequest
15 голосов
/ 27 июля 2010

Сегодня я сталкиваюсь с проблемой, когда мне нужно изменить память на определенный шаблон, например 0x 11223344, чтобы вся память выглядела (в шестнадцатеричном формате):

1122334411223344112233441122334411223344112233441122334411223344...

Я не могу понять, как это сделать с помощью memset (), потому что он занимает всего один байт, а не 4 байта.

Есть идеи?

Спасибо, Бода Цидо.

Ответы [ 7 ]

9 голосов
/ 27 июля 2010

В OS X для этого используется memset_pattern4( ); Я ожидаю, что другие платформы будут иметь аналогичные API.

Я не знаю простого переносимого решения, кроме простого заполнения буфера циклом (что чертовски просто).

6 голосов
/ 27 июля 2010

Рекурсивно копировать память, используя область, которую вы уже заполнили в качестве шаблона за итерацию (O (log (N)):

int fillLen = ...;
int blockSize = 4; // Size of your pattern

memmove(dest, srcPattern, blockSize);
char * start = dest;
char * current = dest + blockSize;
char * end = start + fillLen;
while(current + blockSize < end) {
    memmove(current, start, blockSize);
    current += blockSize;
    blockSize *= 2;
}
// fill the rest
memmove(current, start, (int)end-current);

[EDIT] Что я имею в виду под «O (log (N))», так это то, что время выполнения будет намного быстрее, чем если бы вы заполняли память вручную, поскольку memmove() обычно использует специальные, оптимизированные вручную циклы ассемблера, которые сверкают быстро.

5 голосов
/ 27 июля 2010

Эффективным способом было бы привести указатель к указателю необходимого размера в байтах (например, uint32_t для 4 байтов) и заполнить целыми числами. Хотя это немного уродливо.

char buf[256] = { 0, };
uint32_t * p = (uint32_t *) buf, i;

for(i = 0; i < sizeof(buf) / sizeof(* p); ++i) {
        p[i] = 0x11223344;
}

Не проверено!

4 голосов
/ 27 июля 2010

Если ваш шаблон соответствует wchar_t, вы можете использовать wmemset(), как если бы вы использовали memset().

4 голосов
/ 27 июля 2010

Вы можете установить последовательность где-нибудь, а затем скопировать ее, используя memcpy () туда, где она вам нужна.

2 голосов
/ 27 июля 2010

Ну, обычный способ сделать это - вручную настроить первые четыре байта, а затем memcpy(ptr+4, ptr, len -4)

. Это копирует первые четыре байта во вторые четыре байта, затем копирует вторые четыре байтатретий и т. д.

Обратите внимание, что это «обычно» работает, но не гарантируется, в зависимости от архитектуры вашего процессора и вашей библиотеки времени выполнения C.

0 голосов
/ 10 июня 2014

Использование «memcpy» или «memset» может быть неэффективным методом.

Не отказываться от использования циклов, таких как «for» или «while», когда определенная lib функция делает то же самое.

...