如何在 C 中实现重叠检查 memcpy [英] how to implement overlap-checking memcpy in C
问题描述
这是一个学习练习.我试图通过在复制操作开始之前通知用户是通过还是失败来增强 memcpy.我最大的问题如下.如果我分配两个每个 100 字节的字符数组,并且有两个指针引用每个数组,我怎么知道我正在复制哪个方向?如果我将所有内容从第一个数组复制到第二个数组,如何确保用户不会覆盖原始数组?
This is a learning exercise. I'm attempting to augment memcpy by notifying the user if the copy operation will pass or fail before it begins. My biggest question is the following. If I allocate two char arrays of 100 bytes each, and have two pointers that reference each array, how do I know which direction I am copying? If I copy everything from the first array to the second how do I ensure that the user will not be overwriting the original array?
我当前的解决方案比较指针与目标数组大小的距离.如果两者之间的大小小于我说的会发生覆盖.但是如果它在另一个方向复制呢?我只是有点困惑.
My current solution compares the distance of the pointers from the size of the destination array. If the size between is smaller than I say an overwrite will occur. But what if its copying in the other direction? I'm just kind of confused.
int memcpy2(void *target, void *source, size_t nbytes) {
char * ptr1 = (char *)target;
char * ptr2 = (char *)source;
int i, val;
val = abs(ptr1 - ptr2);
printf("%d, %d\n", val, nbytes + 0);
if (val > nbytes) {
for (i = 0; i < val; i++){
ptr1[i] = ptr2[i];
}
return 0; /*success */
}
return -1; /* error */
}
int main(int argc, char **argv){
char src [100] = "Copy this string to dst1";
char dst [20];
int p;
p = memcpy2(dst, src, sizeof(dst));
if (p == 0)
printf("The element\n'%s'\nwas copied to \n'%s'\nSuccesfully\n", src, dst);
else
printf("There was an error!!\n\nWhile attempting to copy the elements:\n '%s'\nto\n'%s', \n Memory was overlapping", src, dst);
return 0;
}
推荐答案
确定两个内存范围是否重叠的唯一便携方法是:
The only portable way to determine if two memory ranges overlap is:
int overlap_p(void *a, void *b, size_t n)
{
char *x = a, *y = b;
for (i=0; i<n; i++) if (x+i==y || y+i==x) return 1;
return 0;
}
这是因为指针与关系运算符的比较是不确定的,除非它们指向同一个数组.实际上,这种比较确实适用于大多数现实世界的实现,因此您可以执行以下操作:
This is because comparison of pointers with the relational operators is undefined unless they point into the same array. In reality, the comparison does work on most real-world implementations, so you could do something like:
int overlap_p(void *a, void *b, size_t n)
{
char *x = a, *y = b;
return (x<=y && x+n>y) || (y<=x && y+n>x);
}
我希望我的逻辑是正确的;你应该检查一下.如果您想假设可以采用任意指针的差异,则可以进一步简化它.
I hope I got that logic right; you should check it. You can simplify it even more if you want to assume you can take differences of arbitrary pointers.
这篇关于如何在 C 中实现重叠检查 memcpy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!