#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. Если этот код действительно позаимствован из реализации стандартной библиотеки, то это не С, а нечто внешне С-подобное. Чтобы говорить о том, что именно он делает, надо знать особенности поведения той платформы для которой этот код написан. Если же это пользовательский код, то вышеуказанная проблема делает его просто некорректным.
Комментариев нет:
Отправить комментарий