Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » create_bitmap() problem.

This thread is locked; no one can reply to it. rss feed Print
 1   2   3   4 
create_bitmap() problem.
A J
Member #3,025
December 2002
avatar

why should this crash allegro ?
it crashes on the free(bitmap) inside of destroy_bitmap()
it says "Damage after normal block"
which sounds like memory corruption.

and yes i know, im requesting 0,0 size bitmap.

WinXP, alg 4.1.20b4 MSVC7.1 (2003 .net)

BITMAP* p = create_bitmap( 0, 0 );
if ( p )
  destroy_bitmap( p );

___________________________
The more you talk, the more AJ is right. - ML

HoHo
Member #4,534
April 2004
avatar

In graphics.c I found two lines of code:

bitmap = malloc(sizeof(BITMAP) + (sizeof(char *) * height));
bitmap->dat = malloc(width * height * BYTES_PER_PIXEL(color_depth));

If you really don't allocate space for the ->dat then first malloc doesn't even allocate space for the ->dat pointer and effectively bitmap will only get sizeof(BITMAP) bytes of memory and not (sizeof(BITMAP)-sizeof(BITMAP->dat) as it should. For the last four bytes in BITMAP, no memory will get allocated and everything that is written there will probably overwrite something useful.

That means you can't use Allegro with zero-pixel bitmaps. You should be able to create bitmaps of height==1 and width==0

[edit]

Of cource I might be wrong, I just saw the functions code for the first time in my life.

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Elias
Member #358
May 2000

Try to compile in debug mode.

I.e., there is this at the beginning of the function:

ASSERT(width >= 0);
ASSERT(height > 0);

So when run, your program should exit and point you to the line in the source where the problem happened. Using ASSERT simply is the way Allegro currently uses for runtime errors (instead of making the function fail and set an error code or raise an exception or whatever).

In any case, a 0x0 bitmap is not allowed, which the documentation specifically states: http://alleg.sourceforge.net/onlinedocs/en/alleg009.html#create_bitmap

--
"Either help out or stop whining" - Evert

A J
Member #3,025
December 2002
avatar

if you accidently make a 0x0 sized bitmap, and no bitmap is created, then shouldn't create_bitmap() return NULL.
else, you would be lead to beleive you have a bitmap that needs to
get destroy_bitmap() which current crashes.

is there any reason why a create_bitmap(0,0) should return a valid pointer?

___________________________
The more you talk, the more AJ is right. - ML

HoHo
Member #4,534
April 2004
avatar

to make it a bit faster?

I think there should be a way to create bitmaps of 0x0 sizem adding another check shouldn't be so slow that it is only done with debug versions.

allthough this would probably make all image-saving functions a bit more difficult because I'm not sure if the formats even support 0x0 images. Also I think some other functions assume that bitmaps have some image-data with them(e.g 3d rasterizing perhaps)

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

A J
Member #3,025
December 2002
avatar

what the hell are you even considering 0x0 bitmaps as worth creating ?

___________________________
The more you talk, the more AJ is right. - ML

HoHo
Member #4,534
April 2004
avatar

Quote:

what the hell are you even considering 0x0 bitmaps as worth creating ?

Why the hell would anyone even try creating 0x0 bitmaps ;)

Now that I thought of it a bit more I came to conclusion that it would probably be a lot easier to add the check to user side code, not in allegro.

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

A J
Member #3,025
December 2002
avatar

the point of libs is to do as much work for you as possible.
lib should do it. there is no reason it shouldn't.

___________________________
The more you talk, the more AJ is right. - ML

Michael Jensen
Member #2,870
October 2002
avatar

really, would adding if ((w<1) || (h<1)){return(NULL);} to the beginning of create_bitmap() slow it down that much?

(it seems that passing in a negative height could cause all sorts of problems!)

Kitty Cat
Member #2,815
October 2002
avatar

I think ASSERT'ing both w and h would be enough. Creating a 0-sized bitmap is considered an error, AFAIK, and no sane person would do it. So, if it does happen, it would be a bug in the code, which instead of just simply returning NULL, an ASSERT in debug mode would catch more effectively.

However, I do think both width and height need to be 1 or greater. If the width is allowed to be 0, you'll still get a 0-sized bitmap and have the same problems.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

A J
Member #3,025
December 2002
avatar

Why is there so much resistance to having a library function do some sanity checking, what is the point of a library ?

Why would anyone want to create a zero sized bitmap, can anyone give me an example ?

Until BOTH these questions get answered, the only conclusion i can come too is that some of you are resisting for the sake of it.

allegro is a library, its not an application, it needs to SERVE the applications/programmers needs, not the other way around.

___________________________
The more you talk, the more AJ is right. - ML

spellcaster
Member #1,493
September 2001
avatar

The lib will do the Sanity check. As pointed out above, they'll add an ASSERT. So, what's the problem?

--
There are no stupid questions, but there are a lot of inquisitive idiots.

HoHo
Member #4,534
April 2004
avatar

A J said:

Why would anyone want to create a zero sized bitmap, can anyone give me an example ?

You tell us. It was you who started this thread because you had a problem with that. I have never before heard anyone having the same problem.

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Elias
Member #358
May 2000

As also pointed out above, there already is an ASSERT.

--
"Either help out or stop whining" - Evert

spellcaster
Member #1,493
September 2001
avatar

Yes, but width should be asserted to be > 0 as well ;)

--
There are no stupid questions, but there are a lot of inquisitive idiots.

Elias
Member #358
May 2000

Ah, yes, could change this. But a width of 0 at least won't crash of do anything unexpected, so that's why who added the ASSERT made them as they are.

--
"Either help out or stop whining" - Evert

A J
Member #3,025
December 2002
avatar

the problem is, create_bitmap(0,0) returns a valid pointer, that when passed to destroy_bitmap() crashes.
if i have a valid pointer, why does destroy_bitmap() crash ?

___________________________
The more you talk, the more AJ is right. - ML

spellcaster
Member #1,493
September 2001
avatar

Compile your program in debug mode. Do you still have the problem?

--
There are no stupid questions, but there are a lot of inquisitive idiots.

Michael Jensen
Member #2,870
October 2002
avatar

What is ASSERT? I agree with AJ, if the library gives lets you create a bitmap, and returns a valid bitmap without errors, why should it crash on destruction?

But, maybe destroy_bitmap() (since that's where it crashes) should be fixed? Since destroy_bitmap usually isn't called until shutdown, and you can always check bmp->w/bmp->h

I wonder, can you blit to/from the 0 sized bitmap? putpixel? If all of the graphics routines crash while using it, then create_bitmap() should return NULL, but if the only problem is destroy_bitmap, then that's where it should be fixed; regardless of why you'd create one, if it lets you create something you should be able to destroy it!

spellcaster
Member #1,493
September 2001
avatar

It doesn't return a valid bitmap. That's the reason for the crash.
create_bitmap() uses a contract. Validation of this contract takes place only if you compile against the debug version of allegro.

--
There are no stupid questions, but there are a lot of inquisitive idiots.

Michael Jensen
Member #2,870
October 2002
avatar

That's part of my point. If it can't create a valid bitmap it should return NULL, not allocate the wrong amount of memory and return an unusable pointer that can't be deallocated via destroy_bitmap. Just b/c there s no apparant use doesn't mean there is absolutley no use.

Elias
Member #358
May 2000

It doesn't return NULL in debug mode.

--
"Either help out or stop whining" - Evert

A J
Member #3,025
December 2002
avatar

release build, this causes a crash.

BITMAP* p = create_bitmap(0,0);
if ( NULL != p )
  destroy_bitmap( p );

As we seem to be having some trouble communicating exactly why this is considered OK, can i get a simplified bullet point list of reasons why it is OK for a library to crash destroying objects it made?

___________________________
The more you talk, the more AJ is right. - ML

Thomas Harte
Member #33
April 2000
avatar

Quote:

As we seem to be having some trouble communicating exactly why this is considered OK, can i get a simplified bullet point list of reasons why it is OK for a library to crash destroying objects it made?

Because of the general rule that as Allegro is built with speed critical applications in mind, functions do not have to check every single possible error condition and are allowed to crash if you pass wildly unexpected parameters. For example, it is allowed to crash on the following:

persp_project(1, 1, 0, &x, &y);

From that point of view, the question is not "why it is OK for a library to crash destroying objects it made?" but "why should Allegro consider (0, 0) passed to create_bitmap to be sufficiently extraordinary that it may not handle the possibility of error?"

I guess the current dev answer is that this sort of thing is better checked by the user or that it will occur to so few people as to make it prima facie sufficiently extraordinary.

Personally, I agree that a check should be incorporated that requested dimensions are both larger than 0 as Allegro only purports to be able to handle images, not data structures representing "no image".

Bob
Free Market Evangelist
September 2000
avatar

Quote:

As we seem to be having some trouble communicating exactly why this is considered OK, can i get a simplified bullet point list of reasons why it is OK for a library to crash destroying objects it made?

Read up on Design by Contract. This is what Allegro implements. It's a perfectly valid and widely used methodology.

--
- Bob
[ -- All my signature links are 404 -- ]

 1   2   3   4 


Go to: