Помню, что когда я увидел первый раз в коде функцию memcpy ()
— не понял, что это за неведомая зверушка. Никто и думать не думал написать комментарий, который ее объясняет (не, ну потом понимаешь, что эт логично.. не писать же в комментах что делает printf
). При этом по всему коду этих memcpy
было раскидано несколько сотен. Прямо вот пригорошни этих функций, как гроздья спелого винограда висят.. а как их скушать — непонятно. Комментарии в лучшем случае говорили что-то про копировать, что-то про память, буфер и другие умные слова.
Итак. Функция memcpy ()
— от англ. memory copy — копирует содержимое ячейки памяти из одной области в другую; при этом ячейки не должны пересекаться. Определяется при помощи #include <string.h>
memcpy(куда, откуда, размер);
Например:
memcpy(&k, &o, sizeof(struct r));
копирует кусок (некоторое количество байт) размера
struct r
из области памяти &o
в область памяти &k
и возвращает ее (&k
) адрес.
Важно, что это функция копирования непересекающихся массивов. Так делать нельзя:
[---- &o ----]
[---- &k ---]
Иначе на выходе получим нехорошесть. Например, попробуем скопировать:
___&o___ | | 1234567890xxxxx |__ ___| &k
Будет вот что:
___&k___ | | 121212121212xxx
Так что это очень опасная функция. Тут очень просто можно ошибиться с диапазоном (размером) копируемого и потом хрен найдешь ошибку.
Как решить эту проблему, если возникла необходимость копирования пересекающихся ячеек? Помимо memcpy
фукнции в string.h
есть еще горка других функций по работе с памятью, в частности:
void *memmove(void *, const void *, size_t);
Она тоже самое что и memcpy
, но содержимое ячеек может перекрываться (пересекаться). Хотя работает она помедленнее, чем memcpy
Еще в стринга.х
есть:
void *memchr(const void *, int, size_t);
поиск первого вхождения указанного символа в массиве
int memcmp(const void *, const void *, size_t);
сравнивает массивы
void *memset(void *, int, size_t);
заполняет массив указанными символами
Не, ну там до кучи медка 🐻 Все перечислять не буду. Читайте мануал, братья.