C++中如何判断传入缓冲区是否有效?

How to judge whether the incoming buffer is valid in C++?

在我的函数中,内存指针及其大小作为参数传递:

int myFun(uintptr_t* mem_ptr, int mem_size) {
    // Code here
}

有什么方法可以判断这块内存是否真的有效?

(操作系统为 CentOS Linux 7.9.2009 版。)

不要。只是不要。

即使您能找到一种方法来检查指针是否可以安全地取消引用,也不意味着它指向了您认为它指向的位置!它可能指向您的调用堆栈,指向您的 read-only 代码段,指向您正在使用的某些库的静态变量,或您的程序恰好可以访问的内存中的任何其他位置。

传递有效指针的责任应该由函数的调用者承担。为了让调用者更难做一些愚蠢的事情,考虑传递一个 std::vector &std::vector const & 来代替。

很简单。不要写这样的代码。

就像您要检查的那样容易出错。这就是为什么现代 c++ 发明了例如 std::span。跨度代表连续的对象序列,就像您的指针 + 大小一样。但是指针和大小不是您可以在函数调用中轻易混淆的单独值。它是包含两者的单个对象。

实际上,如果大小在编译时已知,它会在类型本身中进行编码,并且跨度仅包含一个指针,使其更小并允许更好地优化函数。

除此之外,您还必须相信您函数的用户不会对您说谎。没有好的方法来验证指针,这是一个困扰垃圾收集器的问题,最好让 OS 通过产生段错误告诉您指针何时完全是垃圾。

注意:使用 span 而不是数组 make 比传递指针 + size 更简单:

#include <span>

int get(std::span<int> x, size_t i) {
    return x[i];
}

int main() {
    int x[] = {2, 3, 5, 7, 11};
    return get(x, 2);
}

std::span 可以从已知大小的数组构造,因此编译器会为您完成所有工作。