c++ - 如何检查两个任意内存范围在 c/c++ 中不重叠

标签 c++ c

假设我需要实现一个非常通用的实用函数,它必须将一个缓冲区复制到另一个缓冲区。根据 c/c++ 标准,使用带有重叠内存的 memcpy 是 UB 另一方面,memmove 可能更慢。我希望能够在任何时候使用 memcmp 实现,并在需要时切换到 memmove。

void copy(const void* src, int src_size, void* dst, int dst_size, int count)
{
    assert(src);
    asserc(dst);
    assert(0 < count);
    assert(count < src_size);
    assert(count < dst_size);

    if (are_overlaped(src, dst, count))
        std::memove(dst, src, count);
    else
        std::memcmp(dst, src, count);
}

按照c/c++标准,对任意指针进行比较或减法是UB。为了编写 are_overlaped 的简单实现,两个指针都必须指向同一数组的项目。所以这是一般情况下的 UB

bool are_overlaped(const void* first, const void* second, int size)
{
    assert(first);
    asserc(second);
    assert(0 < size);

    return std::abs(reinterpret_cast<const char*>(first)
        - reinterpret_cast<const char*>(second)) < size;
}

所以我的问题是如何为任意指针正确实现 are_overlaped?还是有标准的方法来检查这个?

附言。带有拷贝的示例只是为了更好地理解的上下文。我想知道如何实现 are_overlaped 而不是使用或实现复制。

最佳答案

如果这 2 个指针不属于同一个数组,则指针比较是 UB,可以使用 std::less,例如:

template <typename T>
bool are_overlaped(const T* first, const T* second, int size)
{
    // `first` and `second` should be arrays of size greater or equal to `size`
    return first && second
    && (!std::less<>{}(second, first) && std::less<>{}(second, first + size)
      || !std::less<>{}(first, second) && std::less<>{}(first, second + size));


}

关于c++ - 如何检查两个任意内存范围在 c/c++ 中不重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51699331/

相关文章:

计算变化的 C 程序

c++ - 从 C++ STL 关联容器连接键/值

c - 使用未命名管道传递 int 数组

c - C 中的段错误(核心转储),K&R 练习 2.5 的 C 编程语言

c++ - 为什么有两个运算符重载函数?

c - 如何在 C 中定义构造函数

c++ - 想要在Hudson C/C++上工作

c++ - OOP 未在此范围内声明

c++ - 尝试添加处理程序以控制 MFC 窗体时 Visual Studio 崩溃

c++ - poll 与 epoll 洞察力