Прочитав следующее о memcpy()
, я продолжил читать о memmove()
:
To avoid overflows, the size of the arrays pointed by both the destination and source parameters, shall be at least num bytes, and should not overlap (for overlapping memory blocks, memmove is a safer approach).
(ССЫЛКА)
И после проверки программы, используемой для иллюстрации работы memmove()
, я решил настроить ее, используя вместо этого memcpy()
, чтобы увидеть, насколько отличается вывод. К моему удивлению, они одинаковы, даже если это случай перекрывающиеся блоки памяти. Вот программа и вывод, и я приступил к описанию моей путаницы после этого:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "memmove can be very useful......";
//memmove (str+20,str+15,11);
memcpy(str+20,str+15,11); //Simply used memcpy instead of memmove
puts (str);
return 0;
}
Вывод memmove can be very very useful.
Этот вывод такой же, как и для memmove()
. И вот что меня смущает:
1) Почему вывод одинаков для обоих? Поскольку в случае memcpy()
не используется промежуточный буфер, я ожидаю, что копирование начнется с копирования символа в позиции str+15
в позицию str+20
(перезапись того, что там есть). ), символ в позиции str+16
в позицию str+21
и так далее до символа в позиции str+20, который к настоящему времени изменился на символ в позиции str+15, который будет скопирован в позицию str+25.Но это не так, перезаписи нет и это действует так, как будто для записи точной исходной строки используется промежуточный буфер. Вот иллюстрация:
memmove can be very useful...... //Original positions before memcopy
^ ^
str+15 str+20
memmove can be very vseful......
^ copies str+15 to str+20
memmove can be very veeful......
^ copies str+16 to str+21
memmove can be very verful......
^ copies str+17 to str+22
memmove can be very veryul......
^copies str+18 to str+23
memmove can be very very l......
^ copies str+19 to str+24
memmove can be very very v......
^ I expect 'v' to be copied from str+20 to str+25
as str+20 now has 'v',not 'u'
memmove can be very very ve.....
^ I expect 'e' to be copied from str+21 to str+26
as str+21 now has 'e' not 's'
Тогда почему memcpy() копирует его, поскольку memmove может быть очень-очень полезным вместо memmove может быть очень-очень v?
2) Теперь небольшой второстепенный вопрос, вытекающий из этого. О memmove()
говорится следующее (ССЫЛКА)
Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap.
Что именно здесь as if
? Разве промежуточный буфер на самом деле не используется для memmove()
?
str+20
будет перезаписан. - person Rüppell's Vulture   schedule 14.05.2013memcpy
является константой, почему нам даже разрешено писать на него, не создавая ошибок дляmemcpy()
? - person Rüppell's Vulture   schedule 14.05.2013const int i = 10;
......int *ptr = &i;
..*ptr = 100;
..printf("%d",i)
. что такое УБ. но я нарушил завет. Компилятор предупреждает, но я могу это сделать. вы даже не можете быть уверены, что он напечатает - person Koushik Shetty   schedule 14.05.2013