Hi guys,
I've written some code to merge two black and white bitmaps. The code crashes when
writing to the output bitmap.
I've done some detective work but not found out what's wrong. The bad code is somewhere near the end this code :
I just skimmed over, but two things caught my eye:
lock3 = al_lock_bitmap( output, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_WRITEONLY );
if you are reading and writing to the bitmap, shouldn't you use ALLEGRO_LOCK_READWRITE? Not sure if that's causing the crash.
Also, this at the end:
*((uint32_t *) ptr3) = 0xffffffff;
It seems like you're setting the alpha to the combined value of the colour. It should be more like:
*((uint32_t *) ptr3) = 0xff; //a *((uint32_t *) ptr3+1) = 0xff; //b *((uint32_t *) ptr3+2) = 0xff; //g *((uint32_t *) ptr3+3) = 0xff; //r
What I think is happening is that the value you set for the pixel is out of range, causing the crash.
Also, this at the end:
*((uint32_t *) ptr3) = 0xffffffff;
It's perfectly ok to do that. That would set the pixel to white.
I'm not sure what the problem is William, did you try running it through a debugger?
Doesn't that set the value of the array at position ptr3 to 0xffffffff (4294967295)? Let's say I actually wanted to set unsigned char at that position to that value, that's how I would do it, right? (although it would become 0 or something)
Yeah that's what it does.
This:
unsigned char *ptr; *((uint32_t *)ptr) = 0xaabbccdd;
Is identical to this:
unsigned char *ptr; *(ptr+0) = 0xdd; *(ptr+1) = 0xcc; *(ptr+2) = 0xbb; *(ptr+3) = 0xaa;
I wrote this test code:
unsigned char* test = new unsigned char[4]; test[0]=0; test[1]=0; test[2]=0; test[3]=0; *((unsigned char*)test) = 0xffffffff; std::cout<<(int)test[0]<<", "<<(int)test[1]<<", "<<(int)test[2]<<", "<<(int)test[3]<<std::endl; delete []test;
and the output was 255, 0, 0, 0
That's because you casted to unsigned char instead of uint32_t.
Oh, I see now...
Program received signal SIGSEGV, Segmentation fault.
0x004024fd in _fu63___ZSt4cout ()
(gdb)
I've rewritten the code a bit :
The symbol name suggests it's crashing in cout. Compile with debugging (use -g command line switch to gcc/g++). Then try again, it should tell you a line number. Also run "bt" in gdb after it crashes.
g++ colourer.cpp shade_coloured_picture.cpp merge_black_and_white.cpp text_output_management.cpp -o colourer.exe -lallegro-5.0.5-monolith-md
Where do I put the -g in this line please ?
Doesn't really matter, but let's just say "g++ -g ..." .
Thanks.
Got some better output :-
Program received signal SIGSEGV, Segmentation fault.
0x00402530 in _fu64___ZSt4cout () at merge_black_and_white.cpp:228
228 r2 = (int) *(ptr2 + 3);
(gdb)
So that means line 228 in merge_black_and_white.cpp is what's crashing. Is that what we're looking at? If so I don't think your code listing is up to date because that's not what line 228 looks like.
EDIT: make sure your code and executable are matching.
Okay. nm the code so far.
This code :
...gives this output :-
Which means the pitch of lock3 is changed to 255 at some point.
Any ideas what this could be ?
Memory corruption ?
EDIT :
Would this do anything :-
#include <stdint.h>
It's at the top of the source file.
I tried doing
#include <cstdint>
..but the compiler complained.
Oop! I didn't notice this... instead of using ((unsigned char *)lock1) etc, use lock1->data.
Many thanks Trent!