c++ - IsBadReadPtr 的最有效替代品?

标签 c++ windows visual-c++ memory

我有一些 Visual C++ 代码接收指向缓冲区的指针,该缓冲区包含需要由我的代码处理的数据以及该缓冲区的长度。由于我无法控制的错误,有时此指针未初始化或不适合读取我的代码(即,当我尝试访问缓冲区中的数据时它会导致崩溃。)

所以,我需要在使用它之前验证这个指针。我不想使用 IsBadReadPtr 或 IsBadWritePtr,因为每个人都同意它们是错误的。 (谷歌他们的例子。)它们也不是线程安全的——在这种情况下这可能不是问题,尽管线程安全的解决方案会很好。

我在网上看到了通过使用 VirtualQuery 或仅在异常处理程序中执行 memcpy 来完成此任务的建议。但是,需要执行此检查的代码是时间敏感的,因此我需要最有效的检查,而且也是 100% 有效的。任何想法将不胜感激。

要明确一点:我知道最好的做法是只读取错误的指针,让它导致异常,然后追溯到源头并修复实际问题。但是,在这种情况下,错误指针来 self 无法控制的 Microsoft 代码,因此我必须对其进行验证。

还要注意,我不在乎指向的数据是否有效。我的代码正在寻找特定的数据模式,如果没有找到它们将忽略这些数据。我只是想防止在此数据上运行 memcpy 时发生崩溃,并且在尝试 memcpy 时处理异常将需要更改遗留代码中的十几个位置(但如果我有类似 IsBadReadPtr 的调用我只会必须在一处更改代码)。

最佳答案

bool IsBadReadPtr(void* p)
{
    MEMORY_BASIC_INFORMATION mbi = {0};
    if (::VirtualQuery(p, &mbi, sizeof(mbi)))
    {
        DWORD mask = (PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY);
        bool b = !(mbi.Protect & mask);
        // check the page is not a guard page
        if (mbi.Protect & (PAGE_GUARD|PAGE_NOACCESS)) b = true;

        return b;
    }
    return true;
}

关于c++ - IsBadReadPtr 的最有效替代品?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/496034/

相关文章:

java - 在windows命令提示符下获取自己的进程pid

c++ - 如何设置发布/ Debug模式以使用 Microsoft C++ 工具集在命令提示符下编译 cpp 文件

C++ 线程安全 - 在 worker 和 controller 之间交换数据

visual-studio - Visual Studio 2017 中的 "onecore"文件夹

windows - 如何在 Windows 批处理脚本中将 %USERNAME% 的值转换为小写?

c++ - 如果在 Turbo C++ 上有条件

c++ - 在 C++ 中推断函数或仿函数的返回类型

c++ - 我的文件永远打不开?

C++堆状态差异