I've encountered a breakpoint problem while debugging my/a SDL application. It breaks in the call of SDL_FreeSurface() in updateSurface() pointed by the green arrow.
bool Sprite::updateSurface()
{
// WIP:
if (surface)
SDL_FreeSurface(surface); // <-- Here.
int depth;
switch (bytesPP)
{
case 1:
depth = 8;
break;
case 2:
depth = 16;
break;
case 3:
depth = 24;
break;
case 4:
depth = 32;
break;
default:
depth = 0;
break;
}
surface = SDL_CreateRGBSurface(0,width,height,depth,0x00ff0000,0x0000ff00,0x000000ff,0x00000000);
if (!surface)
return false;
/* Lock the screen for direct access to the pixels */
if (SDL_MUSTLOCK(surface))
{
if (SDL_LockSurface(surface) < 0)
{
SDL_GetError();
return false;
}
}
Uint8 *pixel = (Uint8 *) surface->pixels;
Uint32 *write;
for (Uint32 i = 0; i < pixelCount; i++)
{
write = (Uint32 *) pixel;
*write = pixels[i*bytesPP];
pixel += bytesPP;
}
if (SDL_MUSTLOCK(surface))
SDL_UnlockSurface(surface);
return true;
}
test.cpp:
#include "SDL.h"
#include "sprite.h"
Sprite sprite(100,2);
SDL_Surface *screen;
SDL_Event event;
int x, y;
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(640,480,32,0);
SDL_WM_SetCaption("Sprite Test",NULL);
bool running = true;
while (running)
{
if (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
running = false;
break;
case SDL_MOUSEBUTTONDOWN:
SDL_GetMouseState(&x,&y);
sprite.setPixel(x,y,0xffffffff);
break;
default:
break;
}
}
sprite.display(screen,0,0);
SDL_UpdateRect(screen,0,0,0,0);
}
return 0;
}
sprite.h:
#ifndef BASECODE_CPP_SDL_VIDEO_HEADER_SPRITE
#define BASECODE_CPP_SDL_VIDEO_HEADER_SPRITE
#include "SDL_video.h"
class Sprite
{
public:
// Constructor(s):
Sprite();
Sprite(Uint16 size, Uint8 bypp);
Sprite(Uint16 width, Uint16 height, Uint8 bypp);
// Initialize:
void init();
// Create:
bool create(Uint16 size, Uint8 bypp);
bool create(Uint16 width, Uint16 height, Uint8 bypp);
// Enlarge by x 2:
bool enlarge();
// Set:
bool setPixel(Uint16 x, Uint16 y, Uint32 pix);
// Display:
bool display(SDL_Surface *dest, short x, short y);
// Read from source & write to destination:
bool readFrom(SDL_Surface *src, SDL_Rect *srcRect);
bool writeTo(SDL_Surface *dest, SDL_Rect *dstRect);
bool writeTo(SDL_Surface *dest, SDL_Rect *dstRect, SDL_Rect *srcRect);
// Get:
SDL_Surface *getSurface();
// Destructor:
~Sprite();
private:
// Internal members:
bool alloc();
void free();
bool updateSurface();
Uint16 width;
Uint16 height;
Uint32 pixelCount;
Uint8 bytesPP;
Uint32 pixelsSize;
Uint8 *pixels;
SDL_Surface *surface;
bool success;
};
#endif
sprite.cpp:
#include "sprite.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constructor(s):
Sprite::Sprite()
{
init();
}
Sprite::Sprite(Uint16 size, Uint8 bypp)
{
init();
success = create(size,bypp);
}
Sprite::Sprite(Uint16 width, Uint16 height, Uint8 bypp)
{
init();
success = create(width,height,bypp);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize:
void Sprite::init()
{
pixels = NULL;
surface = NULL;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create functions:
bool Sprite::create(Uint16 size, Uint8 bypp)
{
return create(size,size,bypp);
}
bool Sprite::create(Uint16 width, Uint16 height, Uint8 bypp)
{
this->width = width;
this->height = height;
pixelCount = width * height;
bytesPP = bypp;
pixelsSize = pixelCount * bytesPP;
if (!alloc())
return false;
updateSurface();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Update the display surface:
bool Sprite::updateSurface()
{
// WIP:
if (surface)
SDL_FreeSurface(surface); // <-- Here.
int depth;
switch (bytesPP)
{
case 1:
depth = 8;
break;
case 2:
depth = 16;
break;
case 3:
depth = 24;
break;
case 4:
depth = 32;
break;
default:
depth = 0;
break;
}
surface = SDL_CreateRGBSurface(0,width,height,depth,0x00ff0000,0x0000ff00,0x000000ff,0x00000000);
if (!surface)
return false;
/* Lock the screen for direct access to the pixels */
if (SDL_MUSTLOCK(surface))
{
if (SDL_LockSurface(surface) < 0)
{
SDL_GetError();
return false;
}
}
Uint8 *pixel = (Uint8 *) surface->pixels;
Uint32 *write;
for (Uint32 i = 0; i < pixelCount; i++)
{
write = (Uint32 *) pixel;
*write = pixels[i*bytesPP];
pixel += bytesPP;
}
if (SDL_MUSTLOCK(surface))
SDL_UnlockSurface(surface);
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Enlarge by x 2:
bool Sprite::enlarge()
{
// TODO:
return false;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Set:
bool Sprite::setPixel(Uint16 x, Uint16 y, Uint32 pix)
{
// WIP:
if (x < width && y < height)
{
pixels[y * surface->pitch + x * bytesPP] = pix;
}
else
return false;
return updateSurface();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Display:
bool Sprite::display(SDL_Surface *dest, short x, short y)
{
// TODO:
if (SDL_BlitSurface(surface,NULL,dest,NULL))
return false;
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Read from source & write to destination:
/*
bool Sprite::readFrom(SDL_Surface *src, SDL_Rect *srcRect)
{
// TODO:
}
bool Sprite::writeTo(SDL_Surface *dest, SDL_Rect *dstRect)
{
// TODO:
}
bool Sprite::writeTo(SDL_Surface *dest, SDL_Rect *dstRect, SDL_Rect *srcRect)
{
// TODO:
}
*/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Get:
SDL_Surface *Sprite::getSurface()
{
return surface;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Free function:
bool Sprite::alloc()
{
if (pixels)
{
// Free first:
free();
// Or fail:
// return false;
}
pixels = new Uint8[pixelsSize];
if (pixels)
return true;
else
return false;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Free function:
void Sprite::free()
{
if (pixels)
delete [] pixels;
if (surface)
SDL_FreeSurface(surface);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Destructor:
Sprite::~Sprite()
{
free();
}
The output information:
'Sprite.exe': Loaded 'C:\Projects\Programming\Sprite\Debug\Sprite.exe', Symbols loaded.
'Sprite.exe': Loaded 'C:\Windows\System32\ntdll.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\kernel32.dll'
'Sprite.exe': Loaded 'C:\Windows\system\SDL.dll', Binary was not built with debug information.
'Sprite.exe': Loaded 'C:\Windows\System32\advapi32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\rpcrt4.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\gdi32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\user32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\msvcrt.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\winmm.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\ole32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\oleaut32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\oleacc.dll'
'Sprite.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.1_none_bb1f6aa1308c35eb\msvcr90d.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\shimeng.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\apphelp.dll'
'Sprite.exe': Loaded 'C:\Windows\AppPatch\AcLayers.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\shell32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\shlwapi.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\userenv.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\secur32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\winspool.drv'
'Sprite.exe': Loaded 'C:\Windows\System32\mpr.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\imm32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\msctf.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\lpk.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\usp10.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\avgrsstx.dll'
'Sprite.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.6002.18005_none_5cb72f96088b0de0\comctl32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\ddraw.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\dciman32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\setupapi.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\dwmapi.dll'
'Sprite.exe': Unloaded 'C:\Windows\System32\ddraw.dll'
'Sprite.exe': Unloaded 'C:\Windows\System32\dwmapi.dll'
'Sprite.exe': Unloaded 'C:\Windows\System32\setupapi.dll'
'Sprite.exe': Unloaded 'C:\Windows\System32\dciman32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\KBDUS.DLL'
'Sprite.exe': Unloaded 'C:\Windows\System32\KBDUS.DLL'
'Sprite.exe': Loaded 'C:\Windows\System32\KBDSW.DLL'
'Sprite.exe': Unloaded 'C:\Windows\System32\KBDSW.DLL'
HEAP[Sprite.exe]: Heap block at 00A22F60 modified at 00A27D88 past requested size of 4e20
Windows has triggered a breakpoint in Sprite.exe.
This may be due to a corruption of the heap, which indicates a bug in Sprite.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while Sprite.exe has focus.
The output window may have more diagnostic information.
HEAP[Sprite.exe]: Invalid address specified to RtlFreeHeap( 00A20000, 00A22F68 )
Windows has triggered a breakpoint in Sprite.exe.
This may be due to a corruption of the heap, which indicates a bug in Sprite.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while Sprite.exe has focus.
The output window may have more diagnostic information.
HEAP[Sprite.exe]: Heap block at 00A29548 modified at 00A2E370 past requested size of 4e20
Windows has triggered a breakpoint in Sprite.exe.
This may be due to a corruption of the heap, which indicates a bug in Sprite.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while Sprite.exe has focus.
The output window may have more diagnostic information.
HEAP[Sprite.exe]: Invalid address specified to RtlFreeHeap( 00A20000, 00A29550 )
Windows has triggered a breakpoint in Sprite.exe.
This may be due to a corruption of the heap, which indicates a bug in Sprite.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while Sprite.exe has focus.
The output window may have more diagnostic information.
HEAP[Sprite.exe]: Heap block at 02600040 modified at 02604E68 past requested size of 4e20
Windows has triggered a breakpoint in Sprite.exe.
This may be due to a corruption of the heap, which indicates a bug in Sprite.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while Sprite.exe has focus.
The output window may have more diagnostic information.
How do I solve this?