如何在 C 中实现重叠检查 memcpy [英] how to implement overlap-checking memcpy in C

查看:48
本文介绍了如何在 C 中实现重叠检查 memcpy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个学习练习.我试图通过在复制操作开始之前通知用户是通过还是失败来增强 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆