2012-12-16 2 views
1

비트 맵을 생성하는 코드 줄의 주석을 제거 할 때 첫 번째 예외 예외가 발생합니다. 내가 만든 다른 스프라이트와 같은 방식으로이 스프라이트 시트 BMP를 만들었습니다. 오류 메시지는 이것이다 :0xC0000005 : CopyMemory()를 호출 한 후 액세스 위반이 발생했습니다.

First-chance exception at 0x004788ca in HenwayRevamped.exe: 0xC0000005: Access violation writing location 0x02224000. 

내가 마이클 모리슨의 GameEngine 클래스를 기반으로 게임을 실행하고 있습니다. 나는 많은 StackOverflow 스레드 & this handy site을 포함하여이 오류에 대한 몇 시간의 연구를 해왔지만 여전히 문제가 무엇인지 확실하지 않습니다. 여기에 함수 호출는 다음과 같습니다

// 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); 
} 

다음은 기능입니다 :

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; 
} 

는 또한, 여기에 지역 창/w 내 IDE의 스크린 샷입니다. 예외가 throw되는 라인 거터 점에서 녹색 화살표 아이콘 :

Image Hosted by ImageShack.us http://imageshack.us/a/img341/7678/20121216010703am.png

는 문제가있어 내 장치 컨텍스트인가? hDC 변수 아래의 빨간색 느낌표 아이콘은 문제를 지적한 것처럼 보이지만 할당 된 핸들이있어서 확실하지 않습니다. 나는 아이디어를 다 써 버렸고 주인을 향해 달려 가고 있습니다.

+0

당신은 이미이 게시물이 당신의 게시물에 처음으로 나타나는 생성자에서 해고되는 것과 같은'Create()'호출이 아니라는 것을 이미 알고 있어야합니다. 이 코드는 장치 컨텍스트, 너비, 높이 및 색을 예상하는'Create()'를 시작합니다. 당신이 보여주고있는 관계없는'Create()'는 리소스 비트 맵을로드하는 것입니다 (또는 적어도 시도하고 있습니다). – WhozCraig

+0

'pBitmapInfo-> bmiHeader' 안에 무엇이 있습니까?나는'biSizeImage' 값이 잘못 될 것으로 기대합니다. –

+0

헤드 업에 감사드립니다, @WhozCraig; 잘못된 오버로드 된 전화를 잘못 게시했습니다. 실제로 전화가 OP에 있습니다. @Roman,이 호출은 147458을 반환합니다. 이미지의 Windows 속성 창에서 이미지 크기는 147512입니다. 문제가 있다면 어떻게 해결할 수 있습니까? – KongMD

답변

2

액세스 위반하면 대상 버퍼 오버런 있다는 것을 시사 쓰기, 발생 . 다양한 종류의 비트 맵 형식이 있으므로 버퍼의 올바른 크기를 계산하기가 어려울 수 있습니다. 코드가 일부 비트 맵에서 작동하기 때문에 비트 심도, 색상 표 크기, 정렬 또는 해당 선을 따르는 무언가에 대해 잘못된 가정을하고 있다고 생각됩니다.

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에 대한 핸들을 전달할 필요가 없습니다.

+0

그것은 아름답게 작동했고 훨씬 간결합니다. 앞으로도 실패 할 가능성이있는 해킹 된 솔루션을 개선해 주셔서 감사합니다. – KongMD

0

첫 번째 예외는 일반적으로 걱정할 항목이 아니며 일부 설정을 변경하지 않으면 디버거가 멈추지 않아야합니다. 처리되지 않은 예외는 응용 프로그램이 catch하고 처리하지 않은 예외가있는 실제 문제입니다.

디버거가 손상되면 예외 설정을 변경하여 나중에이를 방지하거나 계속 진행하여 처리되지 않은 예외가되는지 확인할 수 있습니다.

여기에 두 번째 기회 대 첫 번째 기회에 대한 몇 가지 추가 정보 : 로마의 통찰력에 http://support.microsoft.com/kb/105675

+0

실제로 게임에서 기능을 깨는 것은 처리되지 않은 예외였습니다. 먼저 [이 스레드] (http://stackoverflow.com/questions/13895604/win32-bitmap-instantiation-breaking-function)에 설명 된대로 문제를 보았고 버그로 인해 "Win32 예외"확인란에 명시 적으로 체크 표시되었습니다 나중에 wow64 에뮬레이션을 사용하십시오. – KongMD

-1

덕분에, 나는 일반적으로 & 작품을 컴파일이 해결 방법을 마련 할 수 있었다. 나는 다른 이미지로 더 많은 예외를 얻을 경우에, 나는 배열을 만들고 그것을 통해 반복,하지만 지금은 작동합니다 :

/* 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); 
관련 문제