#c #указатели #память
Всем привет! Пытаюсь разобраться как работает функция memmove из стандартной библиотеки C. Сама функция: void *ft_memmove(void *dst, const void *src, size_t len) { const char *s; const char *lasts; char *d; char *lastd; d = dst; s = src; if (d < s) while (len--) *d++ = *s++; else { lasts = s + (len - 1); lastd = d + (len - 1); while (len--) *lastd-- = *lasts--; } return (dst); } Помогите, пожалуйста, понять, что происходит в данной части функции: else { lasts = s + (len - 1); lastd = d + (len - 1); while (len--) *lastd-- = *lasts--; }
Ответы
Ответ 1
lasts = s + (len - 1); // Указатель на последний байт блока s lastd = d + (len - 1); // Указатель на последний байт блока d while (len--) // len раз *lastd-- = *lasts--;// выполняем копирование из блока d в блок s // После копирования байта указатели уменьшаются т.е. простое копирование памяти не "слева направо", а "справа налево". Смысл всего действа - чтоб не затереть копированием нужное при перекрывающихся областях памяти.Ответ 2
Если эта ft_memmove действительно является реализацией (или частью реализации?) стандартной функции memmove, то надо заметить, что реализация функций стандартной библиотеки языка С не обязана быть написана на языке С и не подчиняется требованиям языка С. Если рассматривать приведенный вами участок кода как код на языке С, то он внешне выполняет (пытается выполнять) копирование участка памяти "в обратном направлении" - от старших адресов к младшим. Однако с точки зрения языка С приведенный код делает это неправильно - на последней итерации цикла копирования происходит применение оператора -- к значениям указателей lastd и lasts, потенциально указывающих в этот момент на начала неких массивов. Это формально приводит к неопределенному поведению. Так что с точки зрения формального языка С код является некорректной реализацией memmove. Если этот код действительно позаимствован из реализации стандартной библиотеки, то это не С, а нечто внешне С-подобное. Чтобы говорить о том, что именно он делает, надо знать особенности поведения той платформы для которой этот код написан. Если же это пользовательский код, то вышеуказанная проблема делает его просто некорректным.
Комментариев нет:
Отправить комментарий