![]() |
|
VS 2017 Release & Allegro bitmaps |
lCoopsl
Member #16,804
February 2018
|
I'm having a strange problem with Visual Studio 2k17 and I'm hoping to find some insight on the matter here. On Debug it compiles and builds fine. However, on Release it runs into some problems. Here's a simplified version of my program, contained in an header implementation file. 1const int MAX_BITMAPS = 256;
2
3ALLEGRO_BITMAPS *bitmap_STORAGE[MAX_BITMAPS];
4
5enum BITMAPS {
6 SPRITE_A = 1,
7 SPRITE_B,
8 SPRITE_C = 5,
9}
10
11void loadBitmaps() {
12 for (int i = 0; i < MAX_BITMAPS; i++)
13 bitmaps_STORAGE[i] = nullptr;
14
15 ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
16 al_append_path_component(path, "resources");
17 al_change_directory(al_path_cstr(path, '/'));
18 al_destroy_path(path);
19
20 bitmaps_STORAGE[SPRITE_A] = al_load_bitmap("sprite_A.png");
21 bitmaps_STORAGE[SPRITE_B] = al_load_bitmap("sprite_B.png");
22 bitmaps_STORAGE[SPRITE_C] = al_load_bitmap("sprite_C.png");
23}
24
25void destroyBitmaps() {
26 for (int i = 0; i < MAX_BITMAPS; i++) {
27 al_destroy_bitmap(bitmaps_STORAGE[i]);
28 }
29}
Now, I have two instances of issues here. The first instance is setting SPRITE_A's enum to 0. When I do this, al_load_bitmap(...) crashes the program and gives a read access violation. The second instance is looking at the code above, but this time al_destroy_bitmap(...), at the first iteration of the for loop (index 0), crashes the program, giving another read access violation. These are the only allegro calls for creating and deleting, nothing else affects variables directly. Am I experiencing heap corruption or are the allegro functions failing on my part? |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
You need to learn how enums and arrays work. An array is zero-indexed. That means the first element is at index 0. That means you want your enum to start at 0. Your array is uninitialized. It holds random values until you set them to something sensible like 0. This is why your destruction for loop crashes, because it is trying to destroy nonsense memory addresses. enum SPRITE_INDEX { SPRITE_A = 0, SPRITE_B = 1, SPRITE_C = 2, NUM_SPRITES = 3 }; ALLEGRO_BITMAP* sprites[NUM_SPRITES] = {0};
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
lCoopsl
Member #16,804
February 2018
|
Is al_destroy_bitmap() not capable of deleting a nullptr value? I figured initializing the entire array to nullptr would be trivial, but keep it from holding onto garbage before attempting to delete those pointers. |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
The values in the array are not null. They're undefined. You have to initialize them to zero. Whether al_destroy_bitmap handles null values is not the point. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
lCoopsl
Member #16,804
February 2018
|
I'm still running into the issue of al_load_bitmap(...) crashing when SPRITE_A is set to 0. When I set SPRITE_A to anything above 1, then it no longer crashes and the destruction crash happens. Initializing sprite_STORAGE[] with '0' has had no effect. |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Actually, you did initialize the bitmap_storage array to null. Nevermind that, I didn't see it. However, al_load_bitmap should never crash, only return NULL on failure. Post an actual example program that crashes and fails and we can see what's wrong. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
lCoopsl
Member #16,804
February 2018
|
1const int MAX_BITMAPS = 256;
2
3ALLEGRO_BITMAP* bitmaps_SPRITES[MAX_BITMAPS] = { 0 };
4
5enum BITMAPS {
6 //SPLASHES
7 HOME_SPLASH = 2,
8 HOME_PROP_A,
9 STATS_SPLASH,
10 WAR_SPLASH,
11 TITLE_SPLASH,
12// CONFLICT_SPLASH,
13// SKIRMISH_SPLASH,
14
15 FIGHT_HEADER,
16 FIGHT_SPLASH_A,
17
18 //MENUS
19 PAUSE_MENU,
20 LOADOUT_MENU,
21 ABILITIES_MENU,
22
23 ITEM_NOTICE,
24 VICTORY_MENU,
25 DEFEAT_MENU,
26
27
28 //BUTTONS
29 DEFAULT_BUTTON = 20,
30 OPTIONA_BUTTON,
31 OPTIONB_BUTTON,
32 EQUIP_BUTTON,
33
34 FIGHT_START_BUTTON,
35
36 ABILITY_BUTTONS,
37 ATTACK_BUTTON,
38
39 //CLOTHES
40 SWORD_GUY = 50,
41 SWORD_GUY_ROUND,
42 SWORD_GUY_KITE,
43 SWORD_GUY_TOWER,
44 //SWORD_GUY_FULL,
45
46 SPEAR_GUY,
47 SPEAR_GUY_ROUND,
48 SPEAR_GUY_KITE,
49 SPEAR_GUY_TOWER,
50 //SPEAR_GUY_FULL,
51
52 GREAT_GUY,
53 GREAT_GUY_ROUND,
54 GREAT_GUY_KITE,
55 GREAT_GUY_TOWER,
56 //GREAT_GUY_FULL,
57
58 KNIGHT_GUY,
59
60 //MISC
61
62 TOOLTIP = 70,
63 RANK_LABEL,
64
65 SPLATS,
66 HP_BLIP,
67 COMPARE,
68 LEVEL_STAT,
69
70 WEAPON_SLOT,
71 ARMOR_SLOT,
72 SHIELD_SLOT,
73 TRINKET_SLOT,
74
75 SPEED_BAR,
76
77 ANIMATION_TEST,
78 ANIMATION_TEST2,
79
80 CHLOE,
81
82 enumTypeEnd = 255
83};
84
85ALLEGRO_BITMAP *getBitmap(const char *Filename) {
86 ALLEGRO_BITMAP *bitmap = al_load_bitmap(Filename);
87 if (bitmap == NULL) {
88 std::cout << "ERROR LOADING BITMAP: " << Filename << std::endl;
89 bitmap = al_load_bitmap("null.png");
90 }
91 return bitmap;
92}
93
94void loadBitmaps() {
95 //for (int i = 0; i < MAX_BITMAPS; i++)
96 // bitmaps_SPRITES[i] = nullptr;
97
98 ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
99 al_append_path_component(path, "resources");
100 al_change_directory(al_path_cstr(path, '/'));
101 al_destroy_path(path);
102
103 bitmaps_SPRITES[HOME_SPLASH] = getBitmap("backgrounds/homeSplash.png");
104 bitmaps_SPRITES[HOME_PROP_A] = getBitmap("backgrounds/homeSheet.png");
105
106 bitmaps_SPRITES[STATS_SPLASH] = getBitmap("backgrounds/StatScreen.png");
107 bitmaps_SPRITES[WAR_SPLASH] = getBitmap("backgrounds/warView.png");
108 bitmaps_SPRITES[TITLE_SPLASH] = getBitmap("titleSheet.png");
109
110 bitmaps_SPRITES[FIGHT_HEADER] = getBitmap("backgrounds/battleHeader.png");
111 bitmaps_SPRITES[FIGHT_SPLASH_A] = getBitmap("backgrounds/fightSplash00.png");
112
113 bitmaps_SPRITES[PAUSE_MENU] = getBitmap("backgrounds/pauseMenu.png");
114 bitmaps_SPRITES[LOADOUT_MENU] = getBitmap("backgrounds/loadoutMenu.png");
115 bitmaps_SPRITES[ABILITIES_MENU] = getBitmap("backgrounds/abilitiesMenu.png");
116
117 bitmaps_SPRITES[ITEM_NOTICE] = getBitmap("backgrounds/itemNotice.png");
118 bitmaps_SPRITES[VICTORY_MENU] = getBitmap("backgrounds/victoryMenu.png");
119 bitmaps_SPRITES[DEFEAT_MENU] = getBitmap("backgrounds/defeatMenu.png");
120
121 bitmaps_SPRITES[DEFAULT_BUTTON] = getBitmap("defaultButton.png");
122 bitmaps_SPRITES[OPTIONA_BUTTON] = getBitmap("optionButtonA.png");
123 bitmaps_SPRITES[OPTIONB_BUTTON] = getBitmap("optionButtonB.png");
124 bitmaps_SPRITES[EQUIP_BUTTON] = getBitmap("equipButton.png");
125
126 bitmaps_SPRITES[FIGHT_START_BUTTON] = getBitmap("fightStart.png");
127
128 bitmaps_SPRITES[ABILITY_BUTTONS] = getBitmap("abilityButtons.png");
129 bitmaps_SPRITES[ATTACK_BUTTON] = getBitmap("attackButton.png");
130
131 bitmaps_SPRITES[SWORD_GUY] = getBitmap("clothes/swordGuySheet.png");
132 bitmaps_SPRITES[SWORD_GUY_ROUND] = getBitmap("clothes/swordGuyRoundSheet.png");
133 bitmaps_SPRITES[SWORD_GUY_KITE] = getBitmap("clothes/swordGuyKiteSheet.png");
134 bitmaps_SPRITES[SWORD_GUY_TOWER] = getBitmap("clothes/swordGuyTowerSheet.png");
135
136 bitmaps_SPRITES[SPEAR_GUY] = getBitmap("clothes/spearGuySheet.png");
137 bitmaps_SPRITES[SPEAR_GUY_ROUND] = getBitmap("clothes/spearGuyRoundSheet.png");
138 bitmaps_SPRITES[SPEAR_GUY_KITE] = getBitmap("clothes/spearGuyKiteSheet.png");
139 bitmaps_SPRITES[SPEAR_GUY_TOWER] = getBitmap("clothes/spearGuyTowerSheet.png");
140
141 bitmaps_SPRITES[GREAT_GUY] = getBitmap("clothes/greatGuySheet.png");
142 bitmaps_SPRITES[GREAT_GUY_ROUND] = getBitmap("clothes/greatGuyRoundSheet.png");
143 bitmaps_SPRITES[GREAT_GUY_KITE] = getBitmap("clothes/greatGuyKiteSheet.png");
144 bitmaps_SPRITES[GREAT_GUY_TOWER] = getBitmap("clothes/greatGuyTowerSheet.png");
145
146 bitmaps_SPRITES[KNIGHT_GUY] = getBitmap("clothes/knightGuySheet.png");
147
148 bitmaps_SPRITES[TOOLTIP] = getBitmap("tooltip.png");
149 bitmaps_SPRITES[RANK_LABEL] = getBitmap("rankSheet.png");
150
151 bitmaps_SPRITES[SPLATS] = getBitmap("splatSheet.png");
152 bitmaps_SPRITES[HP_BLIP] = getBitmap("hpBlipSheet.png");
153 bitmaps_SPRITES[COMPARE] = getBitmap("compareSheet.png");
154 bitmaps_SPRITES[LEVEL_STAT] = getBitmap("lvlButton.png");
155
156 bitmaps_SPRITES[WEAPON_SLOT] = getBitmap("weapTab.png");
157 bitmaps_SPRITES[ARMOR_SLOT] = getBitmap("armoTab.png");
158 bitmaps_SPRITES[SHIELD_SLOT] = getBitmap("shieTab.png");
159 bitmaps_SPRITES[TRINKET_SLOT] = getBitmap("trinTab.png");
160
161 bitmaps_SPRITES[SPEED_BAR] = getBitmap("speedBar.png");
162
163 bitmaps_SPRITES[ANIMATION_TEST] = getBitmap("test/testSheet.png");
164
165 bitmaps_SPRITES[ANIMATION_TEST2] = getBitmap("clothes/greatGuySheet.png");
166
167 bitmaps_SPRITES[CHLOE] = getBitmap("test/chloe.png");
168}
169
170void destroyBitmaps() {
171 for (int i = 0; i < 0; i++) {
172 std::cout << i << "\t" << bitmaps_SPRITES[i] << std::endl; // CRASHES AT ITERATION 0.
173 al_destroy_bitmap(bitmaps_SPRITES[i]);
174 }
175}
EDIT: Making 'i' start at 2 (or whatever the first bitmap index is, above 1) instead of 0 in the destruction function seems to fixed the destruction crash. Still doesn't answer the question of why it crashes when loading at index 0. |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Something else is going on. Neither one of those functions should be crashing. Have you compiled in debug mode and looked at allegro.log? My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
lCoopsl
Member #16,804
February 2018
|
I've managed to get past the al_load_bitmap() function error. Small mistake with directories. However, another issue has showed up. This time with al_clone_bitmap(), which attempts to clone a bitmap from the array shown. Crashes with a read access violation error upon attempting to clone the first indexed bitmap, even though al_load_bitmap did not return NULL. Again, the strange thing about this is this only appears to be a problem if I assign the first indexed bitmap below an index of 1. If I set the first loaded bitmap's index above 1, then everything works as intended. I'm not entirely sure how to read the allegro log file, should I include it? EDIT: Further testing shows that this error is actually inconsistent. Sometimes it builds, sometimes it doesn't. But when it does build, the first indexed bitmap didn't properly load, and shows as an empty bitmap (No image). Any others loaded afterward are fine though. When I try to exit the program the destruction error happens again, with the first indexed bitmap. EDIT 2: Some debug info... Debug Build: Release Build: WITH FIRST INDEX SET TO 1... Release Build: WITH FIRST INDEX SET TO 2... Something is affecting the first two indexes of this array in Release build. |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
This shouldn't even run. lCoopsl said:
void destroyBitmaps() {
Try to make a minimal example that does the same thing. I don't have all your resources so I can't test your example. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
lCoopsl
Member #16,804
February 2018
|
Not sure how that got in but thats a typo, its iterating over the entire array. 0 should be MAX_BITMAPS. However I've solved the issue somehow. I was loading bitmaps in another file and for some reason, al_load_bitmap(...) was corrupting the pointers in the bitmap storage array in this file indirectly. Still strange since even though I was loading much more than just 2 bitmaps in the separate file, it only affected the first two indexes of the bitmap storage array in this file. And that this was only happening in the Release build. Loading the bitmaps in the separate file before the ones in this one has fixed my issue on all accounts. The only cause I can come up with is my messy ordering of header files. EDIT: Here is the separate file. The original file includes this one. 1#include <allegro5/allegro_font.h>
2#include <allegro5/allegro_ttf.h>
3
4ALLEGRO_FONT *Fonts[Total_Fonts];
5
6enum FONTS {
7 FONT_STANDARD_SMALL,
8 FONT_STANDARD_MEDIUM,
9 FONT_STANDARD_LARGE,
10 FONT_STANDARD_EXTRA,
11 FONT_WARM,
12 FONT_WARM_LARGE,
13 FONT_COLD,
14 FONT_COLD_LARGE,
15
16 Total_Fonts,
17};
18
19ALLEGRO_FONT* getBitmapFont(const char* File) {
20 int ranges[2] = { 48, 57 };
21 ALLEGRO_BITMAP *bitmap = al_load_bitmap(File);
22 ALLEGRO_FONT *font = al_grab_font_from_bitmap(bitmap, 1, ranges);
23 al_destroy_bitmap(bitmap);
24
25 return font;
26}
27
28void loadFonts() {
29 ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
30 al_append_path_component(path, "resources/fonts");
31 al_change_directory(al_path_cstr(path, '/'));
32 al_destroy_path(path);
33
34 Fonts[FONT_STANDARD_SMALL] = al_load_ttf_font("candlebright.ttf", 10, NULL);
35 Fonts[FONT_STANDARD_MEDIUM] = al_load_ttf_font("candlebright.ttf", 12, NULL);
36 Fonts[FONT_STANDARD_LARGE] = al_load_ttf_font("candlebright.ttf", 15, NULL);
37 Fonts[FONT_STANDARD_EXTRA] = al_load_ttf_font("candlebright.ttf", 20, NULL);
38
39 Fonts[FONT_WARM] = getBitmapFont("fontWarm.png");
40 Fonts[FONT_WARM_LARGE] = getBitmapFont("fontWarmBig.png");
41 Fonts[FONT_COLD] = getBitmapFont("fontCold.png");
42 Fonts[FONT_COLD_LARGE] = getBitmapFont("fontColdBig.png");
43}
44
45void destroyFonts() {
46 for (int i = 0; i < Total_Fonts; i++) {
47 al_destroy_font(Fonts[i]);
48 }
49}
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
One thing. You're declaring Fonts before Total_Fonts is named in the enum. Another, you're not declaring the Fonts array as extern and defining it inside another module. That could give you problems. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|