【发布时间】:2017-05-23 06:35:51
【问题描述】:
我想看看restrict 是否会阻止memcpy 访问重叠的内存。 memcpy 函数将 n 个字节从内存区域 src 复制到内存区域 dest直接。内存区域不应重叠。 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不缓冲数据,它就像数据被缓冲一样。例如,这可以通过检查数据在内存中是向前还是向后移动,然后相应地从后向前或从前向后复制来完成。在实践中,它有点复杂,因为将数据复制回前面会出现性能问题,但这就是想法。 -
"restrict 不会阻止访问与
memcpy重叠的内存" - 你为什么期望它这样做?当memcpy无论如何都试图访问重叠的内存(因为你告诉它访问重叠的内存)时,你期望会发生什么? -
printf("%d\n", &itself);导致未定义的行为,%d仅打印int但给出的参数是char * -
这个问题从头到尾都没有意义。对象不能更改它们的地址,那你为什么要一遍又一遍地打印出
itself的地址呢?
标签: c memcpy restrict-qualifier