0
    DWORD dwHandle;

    DWORD dwSize = GetFileVersionInfoSizeEx( FILE_VER_GET_NEUTRAL , strFilePath.c_str() , &dwHandle );
    if( dwSize == 0 )
        break;
    pVersionInfo = new BYTE[ dwSize ];
    bRetVal = GetFileVersionInfoEx( FILE_VER_GET_NEUTRAL , strFilePath.c_str() ,dwHandle , dwSize , &pVersionInfo );
    if( bRetVal == false )
        break;
    UINT uLen;
    VS_FIXEDFILEINFO *pFileInfo;

    bRetVal = VerQueryValue( &pVersionInfo , L"\\" , (LPVOID *)&pFileInfo , &uLen );

    if( bRetVal == false )
        break;
    DWORD dwFileVersionMS = pFileInfo->dwFileVersionMS;
    DWORD dwFileVersionLS = pFileInfo->dwFileVersionLS;

    DWORD dwLeftMost     = HIWORD(dwFileVersionMS);
    DWORD dwSecondLeft   = LOWORD(dwFileVersionMS);
    DWORD dwSecondRight  = HIWORD(dwFileVersionLS);
    DWORD dwRightMost    = LOWORD(dwFileVersionLS);

    strVersion.sprintf( L"%u.%u.%u.%u", dwLeftMost , dwSecondLeft , dwSecondRight , dwRightMost );
}while(0);
if( pVersionInfo )
    delete []pVersionInfo;
return bRetVal;

在调试此代码时,我在删除语句处遇到访问冲突错误。. 谁能告诉我做错了什么。

4

3 回答 3

2

错误是您将指向已分配数据块的指针的指针作为第一个参数传递给VerQueryValue,这导致您将错误的地址传递给函数。这会导致未定义的行为,因为VerQueryValue从内存中不应读取/写入的某个位置读取数据并将数据写入该位置。

解决方案是在这里不使用地址运算符。


更新:你对GetFileVersionInfoEx函数调用做同样的事情。不要将地址运算符用于pVersionInfo.

于 2013-10-01T11:33:23.047 回答
1

错误在行

bRetVal = GetFileVersionInfoEx( FILE_VER_GET_NEUTRAL , strFilePath.c_str() ,dwHandle , dwSize , &pVersionInfo );

正确的调用应该是

bRetVal = GetFileVersionInfoEx( FILE_VER_GET_NEUTRAL , strFilePath.c_str() ,dwHandle , dwSize , pVersionInfo );

来自msdn

BOOL WINAPI GetFileVersionInfoEx(
  _In_        DWORD dwFlags,
  _In_        LPCTSTR lptstrFilename,
  _Reserved_  DWORD dwHandle,
  _In_        DWORD dwLen,
  _Out_       LPVOID lpData
);

该函数GetFileVersionInfoEx()将使用版本信息填充 lpData 指向的缓冲区(或者,在上面更正的示例中,pVersionInfo)。在您的代码中,它将更改指针的值,使其指向内存中的其他位置。

当您调用 时delete[],它会给您异常,因为您的指针的值已更改,并且不再是操作员设置的值new []。换句话说,您正在尝试释放未动态分配的内存。

于 2013-10-01T12:05:02.683 回答
0

是您在另一个线程中的问题的解决方案,带有完整的代码示例,但正如指出的那样,问题是您以错误的方式将指针传递给缓冲区以获取信息,不需要address of操作员。

这是一个代码片段,您的代码已修复为正常工作:

#include <Windows.h>
#include <cstdio>

#pragma comment(lib, "version.lib")

void main(int argc, char** argv)
{
    const wchar_t* strFilePath = L"C:\\Windows\\System32\\kernel32.dll";
    DWORD dwHandle;
    BOOL bRetVal;
    DWORD dwSize = GetFileVersionInfoSizeEx( FILE_VER_GET_NEUTRAL , strFilePath , &dwHandle );
    if( dwSize == 0 )
        return;
    BYTE* pVersionInfo = new BYTE[dwSize];
    bRetVal = GetFileVersionInfoEx( FILE_VER_GET_NEUTRAL , strFilePath , dwHandle , dwSize , pVersionInfo );
    if( bRetVal == false )
        return;
    UINT uLen;
    VS_FIXEDFILEINFO *pFileInfo = NULL;

    bRetVal = VerQueryValue( pVersionInfo , L"\\" , (LPVOID *)&pFileInfo , &uLen );

    if( bRetVal == false )
        return;
    DWORD dwFileVersionMS = pFileInfo->dwFileVersionMS;
    DWORD dwFileVersionLS = pFileInfo->dwFileVersionLS;

    DWORD dwLeftMost     = HIWORD(dwFileVersionMS);
    DWORD dwSecondLeft   = LOWORD(dwFileVersionMS);
    DWORD dwSecondRight  = HIWORD(dwFileVersionLS);
    DWORD dwRightMost    = LOWORD(dwFileVersionLS);

    char pVersion[1024];
    sprintf(pVersion, "%u.%u.%u.%u", dwLeftMost , dwSecondLeft , dwSecondRight , dwRightMost );
    if( pVersionInfo )
        delete []pVersionInfo;
}
于 2013-10-01T12:09:57.663 回答