Я хотел посмотреть, не предотвратит ли restrict
доступ memcpy
к перекрывающейся памяти.
Функция memcpy
копирует n байт из области памяти src в область памяти назначения напрямую. Области памяти не должны перекрываться. memmove
использует буфер, поэтому нет риска перекрытия памяти.
Определитель restrict
говорит, что в течение всего времени существования указателя только сам указатель или значение непосредственно из него (например, pointer + n
) будет иметь доступ к данным этого объекта. Если декларация о намерениях не выполняется и доступ к объекту осуществляется с помощью независимого указателя, это приведет к неопределенному поведению.
#include <stdio.h>
#include <string.h>
#define SIZE 30
int main ()
{
char *restrict itself;
itself = malloc(SIZE);
strcpy(itself, "Does restrict stop undefined behavior?");
printf("%d\n", &itself);
memcpy(itself, itself, SIZE);
puts(itself);
printf("%d\n", &itself);
memcpy(itself-14, itself, SIZE); //intentionally trying to access restricted memory
puts(itself);
printf("%d\n", &itself);
return (0);
}
Выход ()
Собственный адрес: 12345
Ограничивает ли останавливает неопределенное поведение?
Собственный адрес: 12345
Останавливает неопределенное bop неопределенное поведение?
Собственный адрес: 12345
Использует ли memcpy
независимый указатель? Поскольку выходные данные определенно показывают неопределенное поведение, а restrict
не препятствует доступу к перекрывающейся памяти с memcpy
.
Я предполагаю, что memcpy
имеет преимущество в производительности, поскольку копирует данные напрямую, а memmove
использует буфер. Но с современными компьютерами, должен ли я игнорировать эту потенциально более высокую производительность и всегда использовать memmove
, так как это гарантирует отсутствие перекрытий?
memmove
не буферизует данные, он действует так, как если бы данные были буферизованы. Это можно сделать, например, проверив, перемещаются ли данные в памяти вперед или назад, а затем скопировав их соответственно с конца на начало или с начала на конец. На практике это немного сложнее, так как копирование данных назад на передний план имеет проблемы с производительностью, но идея в этом. - person GaspardP   schedule 09.01.2017memcpy
- почему вы ожидали, что это произойдет? И что вы ожидали, когдаmemcpy
все равно попытается получить доступ к перекрывающейся памяти (потому что вы сказали ему получить доступ к перекрывающейся памяти)? - person user253751   schedule 09.01.2017printf("%d\n", &itself);
вызывает неопределенное поведение,%d
печатает толькоint
, но задан аргументchar *
- person M.M   schedule 09.01.2017itself
? - person M.M   schedule 09.01.2017