Important: Is this bug or there is workaround?

Hi,

I'm having such problem, which is not quite bug (but actually it is),

but i would like just to check and see how other people work around this
problem:

Basic idea- I have global object (in example- img) which contains calls to
SDL functions in destructor. When i exit main function using exit() or
return such exit functions are called in such order:

First –
SDL_Quit

img::~img <-- AARGH- THIS IS TOTALLY WRONG!!! As SDL is dead by now, but
~img will call SDL_FreeSurface.
– Last

As you see- the point is, that SDL is deinitialized but SDL functions get’s
called later and in several cases it leads to memory crashes- for example if
"img.image" (see code below) is hardware surface, then there is crash that
will occur in SDL_Surface.c SDL_FreeSurface function:

if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
SDL_VideoDevice *video = current_video;
SDL_VideoDevice *this = current_video;
video->FreeHWSurface(this, surface); <- ERROR- This is Segmentation
Fault, because ‘current_video’ and ‘video’ are NULL!!!
}

So did i made myself clear? Is this a bug or me is just plain stupid? :slight_smile:

Below there is example which should ilustrate the idea. I’m using MSVC 6.0 +
SP5 + SDL 1.2.2 on Windows 98, but as much as i can think this bug does not
depend on that.

Comments? Ideas? Solutions?

Only solution what i can think of, is not make such global objects and make
instead pointers to them, so i can call their destructors when i need (if i
ever call them).

Example why would you might want that>>

class Image {
SDL_Surface *image;
public:
Image() {
image = NULL;
}
~Image() {
if(image) {
SDL_FreeSurface(image);
}
}
loadImage(char *file) {
image = SDL_LoadBMP(file);
}
};

Image img;

int main(int argc, char **argv) {
// Init SDL
// …
// install atexit handler.
image.loadImage(“background.bmp”); // Assume that we have such file,
// so image now points to valid (possibly
hardware) surface
// Use img object as global one.

return 0; // <-- In this place SEG Fault will occur.

}

<<End of example.

Kovacs

Don’t use global objects, and certainly not global objects that have
dependencies.On Sun, Dec 09, 2001 at 03:48:35PM +0200, Kovacs wrote:

First –
SDL_Quit

img::~img <-- AARGH- THIS IS TOTALLY WRONG!!! As SDL is dead by now, but
~img will call SDL_FreeSurface.
– Last

Comments? Ideas? Solutions?


Martin

Bother, said Pooh, as the pin fell out of the grenade.

— Kovacs skrev: > Hi,

I'm having such problem, which is not quite bug

(but actually it is),
but i would like just to check and see how other
people work around this
problem:

Basic idea- I have global object (in example- img)
which contains calls to
SDL functions in destructor. When i exit main
function using exit() or
return such exit functions are called in such order:

First –
SDL_Quit

img::~img <-- AARGH- THIS IS TOTALLY WRONG!!! As
SDL is dead by now, but
~img will call SDL_FreeSurface.
– Last

As you see- the point is, that SDL is deinitialized
but SDL functions get’s
called later and in several cases it leads to memory
crashes- for example if
"img.image" (see code below) is hardware surface,
then there is crash that
will occur in SDL_Surface.c SDL_FreeSurface
function:

if ( (surface->flags & SDL_HWSURFACE) ==
SDL_HWSURFACE ) {
SDL_VideoDevice *video = current_video;
SDL_VideoDevice *this = current_video;
video->FreeHWSurface(this, surface); <- ERROR-
This is Segmentation
Fault, because ‘current_video’ and ‘video’ are
NULL!!!
}

So did i made myself clear? Is this a bug or me is
just plain stupid? :slight_smile:

Below there is example which should ilustrate the
idea. I’m using MSVC 6.0 +
SP5 + SDL 1.2.2 on Windows 98, but as much as i can
think this bug does not
depend on that.

Comments? Ideas? Solutions?

Only solution what i can think of, is not make such
global objects and make
instead pointers to them, so i can call their
destructors when i need (if i
ever call them).

Example why would you might want that>>

class Image {
SDL_Surface *image;
public:
Image() {
image = NULL;
}
~Image() {
if(image) {
SDL_FreeSurface(image);
}
}
loadImage(char *file) {
image = SDL_LoadBMP(file);
}
};

Image img;

int main(int argc, char **argv) {
// Init SDL
// …
// install atexit handler.
image.loadImage(“background.bmp”); // Assume
that we have such file,
// so image now points
to valid (possibly
hardware) surface
// Use img object as global one.

return 0; // <-- In this place SEG Fault will

occur.
}

<<End of example.

Kovacs

try this instead,

int main(int argc, char *argv)
{
Image
img = NULL;
// Init SDL
// …
// install atexit handler.
image = new Image();
image->loadImage(“background.bmp”); // Assume that
we have such
file,
// so image now points to
valid (possibly
hardware) surface
// Use img object as global one.
// delete the image when done which will
// Free the SDL_Surface as well
delete image; image = NULL;

return 0; // <-- In this place SEG Fault will

occur.
}

An alternative is to write a Close method that you can
call whenever you like that will free the SDL_Surface
instead of the destructor

/Anders_____________________________________________________
Nokia 5510, galet utseende, grymt ljud.
G? till http://se.promotions.yahoo.com/nokia/ , uppt?ck
den och vinn den! Sista t?vlingsdagen ?r 16 december 2001.

Kovacs wrote:

Hi,

I’m having such problem, which is not quite bug (but actually it is),
but i would like just to check and see how other people work around this
problem:

Basic idea- I have global object (in example- img) which contains calls to
SDL functions in destructor. When i exit main function using exit() or
return such exit functions are called in such order:

First –
SDL_Quit

img::~img <-- AARGH- THIS IS TOTALLY WRONG!!! As SDL is dead by now, but
~img will call SDL_FreeSurface.
– Last

As you see- the point is, that SDL is deinitialized but SDL functions get’s
called later and in several cases it leads to memory crashes- for example if
"img.image" (see code below) is hardware surface, then there is crash that
will occur in SDL_Surface.c SDL_FreeSurface function:

if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
SDL_VideoDevice *video = current_video;
SDL_VideoDevice *this = current_video;
video->FreeHWSurface(this, surface); <- ERROR- This is Segmentation
Fault, because ‘current_video’ and ‘video’ are NULL!!!
}

So did i made myself clear? Is this a bug or me is just plain stupid? :slight_smile:

Below there is example which should ilustrate the idea. I’m using MSVC 6.0 +
SP5 + SDL 1.2.2 on Windows 98, but as much as i can think this bug does not
depend on that.

Comments? Ideas? Solutions?

Only solution what i can think of, is not make such global objects and make
instead pointers to them, so i can call their destructors when i need (if i
ever call them).

Example why would you might want that>>

class Image {
SDL_Surface *image;
public:
Image() {
image = NULL;
}
~Image() {
if(image) {
SDL_FreeSurface(image);
}
}
loadImage(char *file) {
image = SDL_LoadBMP(file);
}
};

Image img;

int main(int argc, char **argv) {
// Init SDL
// …
// install atexit handler.
image.loadImage(“background.bmp”); // Assume that we have such file,
// so image now points to valid (possibly
hardware) surface
// Use img object as global one.

return 0; // <-- In this place SEG Fault will occur.
}

<<End of example.

Kovacs


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

VC++ and some other compilers do release their allocations in same order
as they were reserved, but if I remember correctly G++ is freeing those
in reverse order (which is the correct way)
So in VC++ you can’t make global object that uses for example console
output in it’s destructor, because cout is already freed due to the
freeing order.

Does SDL_Quit clean up all the memory it allocates for itself? If so,
then there’s no need to delete the image objects in your destructor.
Simply call SDL_WasInit() in the destructor to see if you can omit
deleting the image object or not. If SDL_Quit doesn’t clean up after
itself, then maybe it should to handle a situation like this?

-MarkOn Sun, 9 Dec 2001, Kovacs wrote:

Hi,

I'm having such problem, which is not quite bug (but actually it is),

but i would like just to check and see how other people work around this
problem:

Basic idea- I have global object (in example- img) which contains calls to
SDL functions in destructor. When i exit main function using exit() or
return such exit functions are called in such order:

First –
SDL_Quit

img::~img <-- AARGH- THIS IS TOTALLY WRONG!!! As SDL is dead by now, but
~img will call SDL_FreeSurface.
– Last

As you see- the point is, that SDL is deinitialized but SDL functions get’s
called later and in several cases it leads to memory crashes- for example if
"img.image" (see code below) is hardware surface, then there is crash that
will occur in SDL_Surface.c SDL_FreeSurface function:

if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
SDL_VideoDevice *video = current_video;
SDL_VideoDevice *this = current_video;
video->FreeHWSurface(this, surface); <- ERROR- This is Segmentation
Fault, because ‘current_video’ and ‘video’ are NULL!!!
}

So did i made myself clear? Is this a bug or me is just plain stupid? :slight_smile:

Below there is example which should ilustrate the idea. I’m using MSVC 6.0 +
SP5 + SDL 1.2.2 on Windows 98, but as much as i can think this bug does not
depend on that.

Comments? Ideas? Solutions?

Only solution what i can think of, is not make such global objects and make
instead pointers to them, so i can call their destructors when i need (if i
ever call them).

Example why would you might want that>>

class Image {
SDL_Surface *image;
public:
Image() {
image = NULL;
}
~Image() {
if(image) {
SDL_FreeSurface(image);
}
}
loadImage(char *file) {
image = SDL_LoadBMP(file);
}
};

Image img;

int main(int argc, char **argv) {
// Init SDL
// …
// install atexit handler.
image.loadImage(“background.bmp”); // Assume that we have such file,
// so image now points to valid (possibly
hardware) surface
// Use img object as global one.

return 0; // <-- In this place SEG Fault will occur.

}

<<End of example.

Kovacs

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Mark K. Kim
http://www.cbreak.org/mark/
PGP key available upon request.

VC++ and some other compilers do release their allocations in same order
as they were reserved, but if I remember correctly G++ is freeing those
in reverse order (which is the correct way)
So in VC++ you can’t make global object that uses for example console
output in it’s destructor, because cout is already freed due to the
freeing order.

This is getting off-topic, but I’m not sure I see how VC++ would de-allocate
in allocated order instead of reverse. I’ll assume you’re referring to
stack-based allocations, since the heap requires explicit de-allocation.
Stacks are, however, LIFO constructs - the item on the top of the stack
(last allocated) should be the first one de-allocated. Doing it otherwise
would be… well… silly.

I won’t put ‘silly’ past MS, though.

Could you please elaborate on this behavior?

Thanks,
– Jeff