[Язык C] Функция memcpy ()


Помню, что когда я увидел первый раз в коде функцию 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);
заполняет массив указанными символами

Не, ну там до кучи медка 🐻 Все перечислять не буду. Читайте мануал, братья.


Запись опубликована в рубрике С (Си). Добавьте в закладки постоянную ссылку.

Добавить комментарий

🇬🇧 Attention! Comments with URLs/email are not allowed.
🇷🇺 Комментарии со ссылками/email удаляются автоматически.