来自 PREfast 的指针无效访问(读取 0*1 的 4 个字节)错误

Posted

技术标签:

【中文标题】来自 PREfast 的指针无效访问(读取 0*1 的 4 个字节)错误【英文标题】:Invalid access of pointer (reading 4 bytes of 0*1) error from PREfast 【发布时间】:2011-10-31 05:58:45 【问题描述】:

我正在尝试编译一些看起来像这样的代码: (示例从第 38 行开始,throw 为 45)

VSShader::VSShader(_In_ ICore * const pCore, _In_ const String & path, _In_opt_ const char ** ppArgs) :
    m_Core(pCore), m_Name(path), m_DefaultTechnique(nullptr)

    CGcontext context = m_Core->GetCgContext();

    if (!context || !cgIsContext(context))
    
        throw Exception(L"Voodoo/Core", L"Unable to create parameter (core has no context).", pCore, "VSShader.cpp",  __FUNCTION__  , 45);
    

    int32_t len = m_Name.ToCharStr(0, nullptr);
    std::vector<char> buffer(len);
    path.ToCharStr(len, &buffer[0]);

    m_CgEffect = cgCreateEffectFromFile(context, &buffer[0], ppArgs);

    if (!cgIsEffect(m_CgEffect))
    
        throw Exception(L"Voodoo/Core", L"Failed to create shader.", m_Core, "VSShader.cpp",  __FUNCTION__  , 56);
    
    else
    
        cgSetEffectName(m_CgEffect, &buffer[0]);
    

    this->Link();

被调用的ctor看起来像:

Exception
(
    _In_ wchar_t * Module,
    _In_ wchar_t * Message,
    _In_opt_ ICore * pCore,
    _In_ char * File,
    _In_ char * Function,
    _In_ int Line
);

当我对此进行分析时,我得到了错误:

1>d:\code\voodooshader\framework\core\vsshader.cpp(45): warning C6385: Invalid data: access 'argument 3', 可读大小为 '1*0' bytes, 但 '4'可能会读取字节:行:40、39、41、43

据我所知,这是声称指针有 0 个可读字节,而我在传递它时尝试使用其中的 4 个(分别不正确和正确)。这是一个 32 位的构建,所以指针应该是 4 个字节。

如果我将 throw 中的 m_Core 更改为 nullptr,我不会收到任何错误任何地方,而不仅仅是在 throw 线上(第 39-41 和 43 行也突然没有错误)。

更不寻常的是,如果我将 throw 完全注释掉,我会收到:

1>d:\code\voodooshader\framework\core\vsshader.cpp(56): warning C6385: Invalid data: access 'argument 3', 可读大小为 '1*0' bytes, 但 '4'可能读取的字节数:行:40、39、41、43、48、49、50、52、54

这会在看似 不相关的行上给出相同的错误。

MSDN example for the error 似乎与任何有意义的方式无关,讨论了错误的数组访问。

这是某种已知错误、错误还是我只是误读了它?

更重要的是,我该如何修复它(这是来自编译器或 PREfast 的唯一警告,在 /w4 /wX 上,在 11kloc 代码库中,因为它喜欢堆积可恶的讽刺:P)。

编辑:经过一些讨论和测试,我发现了另外两个奇怪的地方:

如果我从_In_ ICore* const pCore 参数中完全删除注释,则不会出错。

如果我将该参数上的注释更改为_Pre_notnull_ ICore * const pCore,也没有错误。 _Pre_notnull_ 拥有_In_ 的大部分需求,所以这暂时是一个功能性的解决方案,但似乎不正确。

【问题讨论】:

【参考方案1】:

http://social.msdn.microsoft.com/forums/en-US/vstscode/thread/0505289d-4501-4f99-bc06-650c6b481566

Visual Studio 错误。上面链接中的警告抑制示例。 VS2010还没有修复!

【讨论】:

以上是关于来自 PREfast 的指针无效访问(读取 0*1 的 4 个字节)错误的主要内容,如果未能解决你的问题,请参考以下文章

通过批量读取避免 N+One 选择和来自 eclipselink 的无效结果

COM 错误 0x80004003(无效指针)访问 MS Outlook 联系人

Linux设备驱动程序 之 顺序锁

运行所选代码生成器时出错:无效指针(异常来自HRESULT:0x80004003(E_POINTER))

判断野指针,无效指针

C++中的悬垂指针(delete指针后依然可以访问的问题)