Crash on Exit

Post Reply
Mega Shocked
Posts: 2
Joined: Fri Mar 15, 2024 4:32 pm

Crash on Exit

Post by Mega Shocked » Thu Mar 21, 2024 5:07 pm

So far things are going pretty great using citro2d.

The thing is when I press start to exit my program I always crash my 3DS system...

Main.c has this in the body of the loop....

Code: Select all

// Respond to user input
u32 kDown = hidKeysDown();
		
if (kDown & KEY_START)
 {
	break; // break in order to return to hbmenu
}
My C2D_SpriteSheet are declared globally...

Code: Select all

C2D_SpriteSheet GFX_1;
C2D_SpriteSheet GFX_2;
etc...


Then they are initialized in the main before the primary loop

Code: Select all

GFX_1=C2D_SpriteSheetLoad("romfs:/gfx/spriteAtlas1.t3x");
GFX_2=C2D_SpriteSheetLoad("romfs:/gfx/spriteAtlas2.t3x");
Then I assign the values to my struct...

Code: Select all

entity[0].spritesheet = GFX_1;
entity[1].spritesheet = GFX_2;
When I break the main loop the code that appears is...

Code: Select all

C2D_SpriteSheetFree(entity[0].spritesheet);
C2D_SpriteSheetFree(entity[1].spritesheet);

C2D_SpriteSheetFree(GFX_1);
C2D_SpriteSheetFree(GFX_2);

// Deinit libs
C2D_Fini();
C3D_Fini();
gfxExit();
romfsExit();

return 0;
Does anyone happen know where I am going wrong?

User avatar
fincs
( ͡° ͜ʖ ͡°)
Posts: 103
Joined: Mon Jul 12, 2010 9:45 pm
Location: Seville, Spain
Contact:

Re: Crash on Exit

Post by fincs » Fri Mar 22, 2024 5:55 pm

Code: Select all

C2D_SpriteSheetFree(entity[0].spritesheet);
C2D_SpriteSheetFree(entity[1].spritesheet);

C2D_SpriteSheetFree(GFX_1);
C2D_SpriteSheetFree(GFX_2);
This is a double free, because the entities's spritesheets are GFX_1/2 too. In your case, I would recommend that you manage the spritesheet lifetime separately from the entities. In other words, just do this on exit:

Code: Select all

C2D_SpriteSheetFree(GFX_1);
C2D_SpriteSheetFree(GFX_2);
Donate to devkitPro - help us stay alive!

Mega Shocked
Posts: 2
Joined: Fri Mar 15, 2024 4:32 pm

Re: Crash on Exit

Post by Mega Shocked » Sat Mar 23, 2024 4:04 pm

Thanks for getting back to me fincs!

I tried another attempt...

I changed the citro2d call to a pointer so now both C2D calls in my struct appear like this...
(If figured it was wasteful to have 2 C2D_SpriteSheet's declared when I could just point to one of them)

Code: Select all

C2D_Sprite * object_sprite; //< 2D object sprite information
C2D_SpriteSheet * spritesheet; //< 2D object Spritesheet information
Then I assign the struct's spritesheet member like this

Code: Select all

entity[0].spritesheet = &GFX_1;
Everything still works as expected and now when I break the main loop this is the code that appears...

Code: Select all

C2D_SpriteSheetFree(GFX_1);
C2D_SpriteSheetFree(GFX_2);
//...<I have several sprite sheets to free
C2D_SpriteSheetFree(GFX_22);

// Deinit libs
C2D_Fini();
C3D_Fini();
gfxExit();
romfsExit();

return 0;
I still receive a nasty crash screen when I press start...
I posted the "C2D_Sprite * object_sprite" because it and "C2D_SpriteSheet * spritesheet" are the only two Citro2d members in the struct. The rest of the members are u8's, ints, floats etc...

So I have some global "C2D_Sprite's" as well do those need to be freed? I'm not clear on what needs to happen with the exit process...

I also found this blog that seems to refer to a similar problem but the technique described doesn't seem to work for me...
http://darkwebcrypt.blogspot.com/
I am using a New 3DS for my hardware tests.
Last edited by Mega Shocked on Sat Mar 23, 2024 4:18 pm, edited 3 times in total.

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests