Я сталкиваюсь сегодня с проблемой, где я должен изменить память на определенный шаблон как 0x11223344
, так, чтобы целая память была похожа (в шестнадцатеричном числе):
1122334411223344112233441122334411223344112233441122334411223344...
Я не могу выяснить, как сделать это с memset (), потому что требуется только единственный байт, не 4 байта.
Какие-либо идеи?
Спасибо, Boda Cydo.
Эффективным способом было бы привести указатель к указателю необходимого размера в байтах (например, 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;
}
Не проверено!
Если ваш шаблон помещается в wchar_t
, вы можете использовать wmemset()
, как вы бы использовали memset()
.
Вы можете установить последовательность где-нибудь, а затем скопировать ее с помощью memcpy () туда, где вам это нужно.
Что ж, обычный способ сделать это - вручную установить первые четыре байта, а затем memcpy (ptr + 4, ptr, len -4)
Это копирует первые четыре байта во вторые четыре байта, затем копирует вторые четыре байта в третий и так далее.
Обратите внимание, что это «обычно» работает, но не гарантируется, в зависимости от архитектуры вашего процессора и вашей библиотеки времени выполнения C.
В OS X для этого используется memset_pattern4 ()
; Я ожидал, что другие платформы будут иметь аналогичные API.
Я не знаю простого переносимого решения, кроме простого заполнения буфера циклом (что чертовски просто).
Рекурсивно копируйте память, используя уже заполненную область в качестве шаблона для каждой итерации (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 ()
обычно использует специальные, ручные- оптимизированные циклы ассемблера, которые быстро растут.