首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >0xC0000005:调用CopyMemory()后的访问冲突

0xC0000005:调用CopyMemory()后的访问冲突
EN

Stack Overflow用户
提问于 2012-12-16 06:41:29
回答 3查看 1.3K关注 0票数 1

当我取消注释一行创建位图的代码时,我会得到一个第一次出现的异常错误。我以与我制作的其他精灵相同的方式创建了这个spritesheet。错误消息如下:

代码语言:javascript
复制
First-chance exception at 0x004788ca in HenwayRevamped.exe: 0xC0000005: Access violation writing location 0x02224000.

我正在运行一个建立在迈克尔·莫里森的GameEngine课程之上的游戏。我已经对这个错误做了几个小时的研究,包括许多StackOverflow线程& 这个方便的地方,但仍然不确定问题是什么。下面是函数调用

代码语言:javascript
复制
// Create a bitmap from a resource
Bitmap::Bitmap(HDC hDC, UINT uiResID, HINSTANCE hInstance)
  : m_hBitmap(NULL), m_iWidth(0), m_iHeight(0)
{
  Create(hDC, uiResID, hInstance);
}

这是函数

代码语言:javascript
复制
BOOL Bitmap::Create(HDC hDC, UINT uiResID, HINSTANCE hInstance)
{
  // Free any previous DIB info
  Free();

  // Find the bitmap resource
  HRSRC hResInfo = FindResource(hInstance, MAKEINTRESOURCE(uiResID), RT_BITMAP);
  if (hResInfo == NULL)
    return FALSE;

  // Load the bitmap resource
  HGLOBAL hMemBitmap = LoadResource(hInstance, hResInfo);
  if (hMemBitmap == NULL)
    return FALSE;

  // Lock the resource and access the entire bitmap image
  PBYTE pBitmapImage = (BYTE*)LockResource(hMemBitmap);
  if (pBitmapImage == NULL)
  {
    FreeResource(hMemBitmap);
    return FALSE;
  }

  // Store the width and height of the bitmap
  BITMAPINFO* pBitmapInfo = (BITMAPINFO*)pBitmapImage;
  m_iWidth = (int)pBitmapInfo->bmiHeader.biWidth;
  m_iHeight = (int)pBitmapInfo->bmiHeader.biHeight;

  // Get a handle to the bitmap and copy the image bits
  PBYTE pBitmapBits;
  m_hBitmap = CreateDIBSection(hDC, pBitmapInfo, DIB_RGB_COLORS,
    (PVOID*)&pBitmapBits, NULL, 0);
  if ((m_hBitmap != NULL) && (pBitmapBits != NULL))
  {
    const PBYTE pTempBits = pBitmapImage + pBitmapInfo->bmiHeader.biSize +
      pBitmapInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD);


    CopyMemory(pBitmapBits, pTempBits, pBitmapInfo->bmiHeader.biSizeImage);

    // Unlock and free the bitmap graphics object
    UnlockResource(hMemBitmap);
    FreeResource(hMemBitmap);
    return TRUE;
  }

  // Something went wrong, so cleanup everything
  UnlockResource(hMemBitmap);
  FreeResource(hMemBitmap);
  Free();
  return FALSE;
}

另外,这里还有我的IDE w/ Locals窗口的屏幕截图。沟槽中的绿色箭头图标指向抛出异常的行:

由http://imageshack.us/a/img341/7678/20121216010703am.png ImageShack.us托管的图像

是我的设备环境造成的问题吗?hDC变量下的红色感叹号看起来可能指向了问题,但是它分配了一个句柄,所以我不确定。我的想法已经用完了,我要求助于大师。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-16 17:19:22

访问冲突发生在写时,这意味着您正在超出目标缓冲区。位图格式有许多不同的类型,因此很难为缓冲区计算合适的大小。您的代码确实适用于一些位图,因此我怀疑您对于位深度、颜色表大小、对齐方式或其他方面都有错误的假设。

无论何时,您都可以让Windows来完成以下工作:

代码语言:javascript
复制
    BOOL Bitmap::Create2(UINT uiResID, HINSTANCE hInstance) {
        BOOL bSuccess = FALSE;
        Free();
        m_hBitmap = reinterpret_cast<HBITMAP>(
            ::LoadImage(hInstance, MAKEINTRESOURCE(uiResID), IMAGE_BITMAP,
                        0, 0, LR_CREATEDIBSECTION));
        if (m_hBitmap != NULL) {
            BITMAP bmp;
            if (::GetObject(m_hBitmap, sizeof(bmp), &bmp) == sizeof(bmp)) {
                m_iWidth = bmp.bmWidth;
                m_iHeight = bmp.bmHeight;
                bSuccess = TRUE;
            }
        }
        return bSuccess;
    }

这应该适用于所有有效的位图。请注意,您不再需要将句柄传递给DC。

票数 2
EN

Stack Overflow用户

发布于 2012-12-16 06:52:00

第一次机会异常通常不需要担心,除非您已经更改了一些设置,否则调试器不应该停止它们。未处理的异常是一个实际问题,其中存在应用程序没有捕获和处理的异常。

如果调试器发生故障,则可以更改异常设置以防止将来发生这种情况,或者只需继续,查看它是否会变成未处理的异常。

关于第一次机会与第二次机会的更多信息:http://support.microsoft.com/kb/105675

票数 0
EN

Stack Overflow用户

发布于 2012-12-16 15:46:43

多亏了罗曼的洞察力,我才能想出一个能正常编译和工作的解决办法。如果对其他图像有更多的异常,我将创建一个数组并遍历它,但是现在这是可行的:

代码语言:javascript
复制
/*  This causes strange black lines at the top of some sprites. Pixel bleeding?
    if(pBitmapInfo->bmiHeader.biSizeImage > neededBytes )
        CopyMemory(pBitmapBits, pTempBits, neededBytes);
    else
        CopyMemory(pBitmapBits, pTempBits, pBitmapInfo->bmiHeader.biSizeImage);
    */

    //workaround for powerup sprite
    if(pBitmapInfo->bmiHeader.biSizeImage == 294914 )
        CopyMemory(pBitmapBits, pTempBits, neededBytes);
    else
        CopyMemory(pBitmapBits, pTempBits, pBitmapInfo->bmiHeader.biSizeImage);
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13899209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档