new memory leak patch

Taylor Richards mtrs at bellsouth.net
Sun Jun 8 11:56:44 EDT 2003


Here is a new memory leak patch.  I've been going over this stuff for
the past four days so if I haven't gotten everything by now it's time to
stop trying.  If anyone sees any problem let me know, otherwise I'll
commit tomorrow.


Taylor

-- 
Taylor Richards <mtrs at bellsouth.net>
-------------- next part --------------
? memleak.patch
Index: include/cutscenes.h
===================================================================
RCS file: /cvs/cvsroot/freespace2/include/cutscenes.h,v
retrieving revision 1.2
diff -u -b -B -r1.2 cutscenes.h
--- include/cutscenes.h	2002/06/09 04:41:12	1.2
+++ include/cutscenes.h	2003/06/08 15:50:19
@@ -73,6 +73,7 @@
 
 // initializa table data
 void cutscene_init();
+void cutscene_tbl_close();
 int cutscene_get_cd_num(char *filename);
 
 
Index: include/medals.h
===================================================================
RCS file: /cvs/cvsroot/freespace2/include/medals.h,v
retrieving revision 1.4
diff -u -b -B -r1.4 medals.h
--- include/medals.h	2003/06/03 04:00:39	1.4
+++ include/medals.h	2003/06/08 15:50:19
@@ -108,6 +108,7 @@
 // return 0 if the screen should close (used for MM_POPUP mode)
 int medal_main_do();
 void medal_main_close();
+void medal_tbl_close();
 
 //void init_medal_palette();
 void init_medal_bitmaps();
Index: include/missioncampaign.h
===================================================================
RCS file: /cvs/cvsroot/freespace2/include/missioncampaign.h,v
retrieving revision 1.3
diff -u -b -B -r1.3 missioncampaign.h
--- include/missioncampaign.h	2003/05/25 02:30:42	1.3
+++ include/missioncampaign.h	2003/06/08 15:50:19
@@ -424,7 +424,8 @@
 extern void mission_campaign_mission_over( void );
 
 // frees all memory at game close time
-extern void mission_campaign_close( void );
+extern void mission_campaign_close( void );		// gets called in more than game close
+extern void mission_campaign_shutdown( void );	// only called in game close
 
 // read in a campaign file.  Used by Fred.
 int mission_campaign_load_fred(char *filename, char *name_verify = NULL);
Index: include/missionweaponchoice.h
===================================================================
RCS file: /cvs/cvsroot/freespace2/include/missionweaponchoice.h,v
retrieving revision 1.2
diff -u -b -B -r1.2 missionweaponchoice.h
--- include/missionweaponchoice.h	2002/06/09 04:41:14	1.2
+++ include/missionweaponchoice.h	2003/06/08 15:50:19
@@ -159,6 +159,7 @@
 void weapon_select_common_init();
 void weapon_select_do(float frametime);
 void weapon_select_close();
+void weapon_select_close_team();
 
 void	wl_update_parse_object_weapons(p_object *pobjp, wss_unit *slot);
 int	wl_update_ship_weapons(int objnum, wss_unit *slot);
Index: include/playermenu.h
===================================================================
RCS file: /cvs/cvsroot/freespace2/include/playermenu.h,v
retrieving revision 1.2
diff -u -b -B -r1.2 playermenu.h
--- include/playermenu.h	2002/06/09 04:41:14	1.2
+++ include/playermenu.h	2003/06/08 15:50:19
@@ -73,6 +73,7 @@
 
 // tooltips
 void player_tips_init();
+void player_tips_close();
 void player_tips_popup();
 
 #endif
Index: include/scoring.h
===================================================================
RCS file: /cvs/cvsroot/freespace2/include/scoring.h,v
retrieving revision 1.3
diff -u -b -B -r1.3 scoring.h
--- include/scoring.h	2003/05/25 02:30:42	1.3
+++ include/scoring.h	2003/06/08 15:50:20
@@ -299,6 +299,7 @@
 void init_scoring_element(scoring_struct *s);
 
 void parse_rank_tbl();
+void scoring_tbl_close();
 void scoring_level_init( scoring_struct *score );
 void scoring_level_close(int accepted = 1);
 void scoring_backout_accept( scoring_struct *score );
Index: include/weapon.h
===================================================================
RCS file: /cvs/cvsroot/freespace2/include/weapon.h,v
retrieving revision 1.3
diff -u -b -B -r1.3 weapon.h
--- include/weapon.h	2003/05/25 02:30:42	1.3
+++ include/weapon.h	2003/06/08 15:50:20
@@ -616,5 +616,6 @@
 // return handle to explosion ani
 int weapon_get_expl_handle(int weapon_expl_index, vector *pos, float size);
 
-#endif
+void weapon_close();	// called in game_shutdown() to free malloc'd memory
 
+#endif
Index: src/cutscene/cutscenes.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/cutscene/cutscenes.cpp,v
retrieving revision 1.7
diff -u -b -B -r1.7 cutscenes.cpp
--- src/cutscene/cutscenes.cpp	2003/05/25 02:30:42	1.7
+++ src/cutscene/cutscenes.cpp	2003/06/08 15:50:20
@@ -231,6 +231,19 @@
 #endif  // FS1_DEMO
 }
 
+// free up memory from table parsing
+void cutscene_tbl_close()
+{
+	int i;
+	
+	for (i=0; i<MAX_CUTSCENES; i++) {
+		if (Cutscenes[i].description) {
+			free(Cutscenes[i].description);
+			Cutscenes[i].description = NULL;
+		}
+	}
+}
+
 // function to return 0 based index of which CD a particular movie is on
 // returns -1 on failure.
 int cutscenes_get_cd_num( char *filename )
Index: src/freespace2/freespace.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/freespace2/freespace.cpp,v
retrieving revision 1.30
diff -u -b -B -r1.30 freespace.cpp
--- src/freespace2/freespace.cpp	2003/06/03 04:00:39	1.30
+++ src/freespace2/freespace.cpp	2003/06/08 15:50:25
@@ -1659,13 +1659,13 @@
 void game_level_close()
 {
 	// De-Initialize the game subsystems
-	message_mission_shutdown();
 	event_music_level_close();
 	game_stop_looped_sounds();
 	snd_stop_all();
 	obj_snd_level_close();					// uninit object-linked persistant sounds
 	gamesnd_unload_gameplay_sounds();	// unload gameplay sounds from memory
 	anim_level_close();						// stop and clean up any anim instances
+	message_mission_shutdown();				// called after anim_level_close() to make sure anim instances are free
 	shockwave_level_close();
 	fireball_level_close();	
 	shield_hit_close();
@@ -7144,6 +7144,13 @@
 			game_do_cd_check_specific(FS_CDROM_VOLUME_2, 2);
 #endif // defined(OEM_BUILD)
 		}
+
+		for (int i=0; i<2; i++) {
+			if (plist[i] != NULL) {
+				free(plist[i]);
+				plist[i] = NULL;
+			}
+		}
 #endif
 	}
 
@@ -7293,10 +7300,12 @@
 	shockwave_close();			// release any memory used by shockwave system	
 	fireball_close();				// free fireball system
 	ship_close();					// free any memory that was allocated for the ships
+	weapon_close();					// free any memory that was allocated for the weapons
 	hud_free_scrollback_list();// free space allocated to store hud messages in hud scrollback
 	unload_animating_pointer();// frees the frames used for the animating mouse pointer
 	bm_unload_all();				// free bitmaps
 	mission_campaign_close();	// close out the campaign stuff
+	mission_campaign_shutdown();	// get anything that mission_campaign_close can't do
 	multi_voice_close();			// close down multiplayer voice (including freeing buffers, etc)
 	multi_log_close();
 #ifdef MULTI_USE_LAG
@@ -7308,7 +7317,13 @@
 	main_hall_close();
 #endif
 	training_menu_close();
+	lcl_close();				// be sure localization is closed out
 	gr_close();
+
+	// free left-over memory from parsed tables
+	cutscene_tbl_close();
+	medal_tbl_close();
+	scoring_tbl_close();
 
 	extern void joy_close();
 	joy_close();
Index: src/graphics/font.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/graphics/font.cpp,v
retrieving revision 1.6
diff -u -b -B -r1.6 font.cpp
--- src/graphics/font.cpp	2003/05/25 02:30:42	1.6
+++ src/graphics/font.cpp	2003/06/08 15:50:25
@@ -763,7 +763,39 @@
 
 void gr_font_close()
 {
+	font *fnt;
+	int i;
 
+	fnt = Fonts;
+
+	for (i=0; i<Num_fonts; i++) {
+		if (fnt->kern_data) {
+			free(fnt->kern_data);
+		}
+
+		if (fnt->char_data) {
+			free(fnt->char_data);
+		}
+
+		if (fnt->pixel_data) {
+			free(fnt->pixel_data);
+		}
+
+		if (fnt->bm_data) {
+			free(fnt->bm_data);
+		}
+
+
+		if (fnt->bm_u) {
+			free(fnt->bm_u);
+		}
+
+		if (fnt->bm_v) {
+			free(fnt->bm_v);
+		}
+
+		fnt++;
+	}
 }
 
 // Returns -1 if couldn't init font, otherwise returns the
Index: src/localization/localize.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/localization/localize.cpp,v
retrieving revision 1.5
diff -u -b -B -r1.5 localize.cpp
--- src/localization/localize.cpp	2003/06/03 04:00:40	1.5
+++ src/localization/localize.cpp	2003/06/08 15:50:25
@@ -487,9 +487,18 @@
 // shutdown localization
 void lcl_close()
 {
+	int i;
+
 	// if the filename exists, free it up
 	if(Lcl_ext_filename != NULL){
 		free(Lcl_ext_filename);
+	}
+
+	// free the Xstr_table
+	for (i=0; i<XSTR_SIZE; i++) {
+		if (Xstr_table[i].str != NULL) {
+			free(Xstr_table[i].str);
+		}
 	}
 };
 
Index: src/menuui/credits.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/menuui/credits.cpp,v
retrieving revision 1.5
diff -u -b -B -r1.5 credits.cpp
--- src/menuui/credits.cpp	2003/05/25 02:30:42	1.5
+++ src/menuui/credits.cpp	2003/06/08 15:50:25
@@ -394,6 +394,7 @@
 		int size;
 		size = cfilelength(fp);
 		Credit_text = (char *) malloc(size + 200);
+		Credit_text_malloced = 1;
 		cfclose(fp);
 
 		// open localization and parse
Index: src/menuui/playermenu.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/menuui/playermenu.cpp,v
retrieving revision 1.5
diff -u -b -B -r1.5 playermenu.cpp
--- src/menuui/playermenu.cpp	2003/05/25 02:30:42	1.5
+++ src/menuui/playermenu.cpp	2003/06/08 15:50:25
@@ -773,6 +773,8 @@
 	if (Player_select_force_bastion) {
 		Player->on_bastion = 1;
 	}
+	
+	player_tips_close();
 }
 
 void player_select_set_input_mode(int n)
@@ -1556,6 +1558,21 @@
 	lcl_ext_close();
 #endif
 }
+
+void player_tips_close()
+{
+#ifndef MAKE_FS1
+	int i;
+	
+	for (i=0; i<MAX_PLAYER_TIPS; i++) {
+		if (Player_tips[i]) {
+			free(Player_tips[i]);
+			Player_tips[i] = NULL;
+		}
+	}
+#endif
+}
+
 void player_tips_popup()
 {
 #ifndef MAKE_FS1
Index: src/mission/missionbriefcommon.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/mission/missionbriefcommon.cpp,v
retrieving revision 1.8
diff -u -b -B -r1.8 missionbriefcommon.cpp
--- src/mission/missionbriefcommon.cpp	2003/06/03 04:00:40	1.8
+++ src/mission/missionbriefcommon.cpp	2003/06/08 15:50:25
@@ -2463,6 +2463,7 @@
 {
 	brief_close_map();
 	brief_unload_anims();
+	mission_brief_common_reset();
 }
 
 
Index: src/mission/missioncampaign.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/mission/missioncampaign.cpp,v
retrieving revision 1.7
diff -u -b -B -r1.7 missioncampaign.cpp
--- src/mission/missioncampaign.cpp	2003/05/25 02:30:42	1.7
+++ src/mission/missioncampaign.cpp	2003/06/08 15:50:26
@@ -1550,12 +1550,43 @@
  			free ( Campaign.missions[i].events );
 		}
 
+		// the next three are strdup'd return values from parselo.cpp
+		if (Campaign.missions[i].mission_loop_desc) {
+			free(Campaign.missions[i].mission_loop_desc);
+		}
+
+		if (Campaign.missions[i].mission_loop_brief_anim) {
+			free(Campaign.missions[i].mission_loop_brief_anim);
+		}
+
+		if (Campaign.missions[i].mission_loop_brief_sound) {
+			free(Campaign.missions[i].mission_loop_brief_sound);
+		}
+
 		if ( !Fred_running ){
 			sexp_unmark_persistent(Campaign.missions[i].formula);		// free any sexpression nodes used by campaign.
 		}
 
 		Campaign.missions[i].num_goals = 0;
 		Campaign.missions[i].num_events = 0;
+	}
+}
+
+// call from game_shutdown() ONLY!!!
+void mission_campaign_shutdown()
+{
+	int i;
+	
+	for (i=0; i<MAX_CAMPAIGNS; i++) {
+		if (Campaign_names[i]) {
+			free(Campaign_names[i]);
+			Campaign_names[i] = NULL;
+		}
+		
+		if (Campaign_file_names[i]) {
+			free(Campaign_file_names[i]);
+			Campaign_file_names[i] = NULL;
+		}
 	}
 }
 
Index: src/mission/missionmessage.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/mission/missionmessage.cpp,v
retrieving revision 1.4
diff -u -b -B -r1.4 missionmessage.cpp
--- src/mission/missionmessage.cpp	2003/05/25 02:30:43	1.4
+++ src/mission/missionmessage.cpp	2003/06/08 15:50:27
@@ -826,7 +826,7 @@
 // called to do cleanup when leaving a mission
 void message_mission_shutdown()
 {
-	int i;
+	int i, j;
 
 	mprintf(("Unloading in mission messages\n"));
 
@@ -839,6 +839,15 @@
 		}
 	}
 
+	// free up remaining anim data
+	for (i=0; i<Num_message_avis; i++) {
+		if (Message_avis[i].anim_data != NULL) {
+			for (j=0; j<Message_avis[i].anim_data->ref_count; j++) {
+				anim_free(Message_avis[i].anim_data);
+			}
+		}
+		Message_avis[i].anim_data = NULL;
+	}
 }
 
 // functions to deal with queuing messages to the message system.
@@ -1216,6 +1225,10 @@
 	// check to see if the avi has been loaded.  If not, then load the AVI.  On an error loading
 	// the avi, set the top level index to -1 to avoid multiple tries at loading the flick.
 	if ( hud_gauge_active(HUD_TALKING_HEAD) ) {
+		// if there is something already here that's not this same file then go ahead a let go of it
+		if ( (anim_info->anim_data != NULL) && stricmp(ani_name, anim_info->anim_data->name) )
+			anim_free(anim_info->anim_data);
+
 		anim_info->anim_data = anim_load( ani_name, 0 );
 	} else {
 		return;
Index: src/missionui/missionscreencommon.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/missionui/missionscreencommon.cpp,v
retrieving revision 1.5
diff -u -b -B -r1.5 missionscreencommon.cpp
--- src/missionui/missionscreencommon.cpp	2003/05/25 02:30:43	1.5
+++ src/missionui/missionscreencommon.cpp	2003/06/08 15:50:27
@@ -1153,6 +1153,9 @@
 
 	nprintf(("Alan","entering common_select_close()\n"));
 	
+	// catch open anims that weapon_select_init_team() opened when not in weapon_select
+	weapon_select_close_team();
+
 	weapon_select_close();
 	if(Game_mode & GM_MULTIPLAYER){
 		multi_ts_close();
Index: src/missionui/missionweaponchoice.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/missionui/missionweaponchoice.cpp,v
retrieving revision 1.5
diff -u -b -B -r1.5 missionweaponchoice.cpp
--- src/missionui/missionweaponchoice.cpp	2003/05/25 02:30:43	1.5
+++ src/missionui/missionweaponchoice.cpp	2003/06/08 15:50:28
@@ -2118,6 +2118,17 @@
 	wl_fill_slots();
 }
 
+// close out what weapon_select_init_team() set up but only when we are not acutally
+// in the weapon select screen
+void weapon_select_close_team()
+{
+	if (Weapon_select_open)
+		return;
+
+	wl_unload_all_anim_instances();
+	wl_unload_all_anims();
+}
+
 // This init is called even before the weapons loadout screen is entered.  It is called when the
 // briefing state is entered.
 void weapon_select_common_init()
Index: src/model/modelread.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/model/modelread.cpp,v
retrieving revision 1.7
diff -u -b -B -r1.7 modelread.cpp
--- src/model/modelread.cpp	2003/01/30 19:43:57	1.7
+++ src/model/modelread.cpp	2003/06/08 15:50:29
@@ -793,6 +793,11 @@
 		free(pm->docking_bays);
 	}
 
+	// this is from ship.cpp but we don't get the polymodel there so free here
+	if ( pm->ship_bay != NULL ) {
+		free(pm->ship_bay);
+		pm->ship_bay = NULL;
+	}
 
 	if ( pm->thrusters )	{
 		free(pm->thrusters);
Index: src/ship/ship.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/ship/ship.cpp,v
retrieving revision 1.6
diff -u -b -B -r1.6 ship.cpp
--- src/ship/ship.cpp	2003/05/25 02:30:44	1.6
+++ src/ship/ship.cpp	2003/06/08 15:50:33
@@ -7016,6 +7016,50 @@
 			free(Ship_info[i].subsystems);
 		}
 	}
+
+	// free info from parsed table data
+	for (i=0; i<MAX_SHIP_TYPES; i++) {
+		if(Ship_info[i].type_str != NULL){
+			free(Ship_info[i].type_str);
+			Ship_info[i].type_str = NULL;
+		}
+		if(Ship_info[i].maneuverability_str != NULL){
+			free(Ship_info[i].maneuverability_str);
+			Ship_info[i].maneuverability_str = NULL;
+		}
+		if(Ship_info[i].armor_str != NULL){
+			free(Ship_info[i].armor_str);
+			Ship_info[i].armor_str = NULL;
+		}
+		if(Ship_info[i].manufacturer_str != NULL){
+			free(Ship_info[i].manufacturer_str);
+			Ship_info[i].manufacturer_str = NULL;
+		}
+		if(Ship_info[i].desc != NULL){
+			free(Ship_info[i].desc);
+			Ship_info[i].desc = NULL;
+		}
+		if(Ship_info[i].tech_desc != NULL){
+			free(Ship_info[i].tech_desc);
+			Ship_info[i].tech_desc = NULL;
+		}
+		if(Ship_info[i].ship_length != NULL){
+			free(Ship_info[i].ship_length);
+			Ship_info[i].ship_length = NULL;
+		}
+		if(Ship_info[i].gun_mounts != NULL){
+			free(Ship_info[i].gun_mounts);
+			Ship_info[i].gun_mounts = NULL;
+		}
+		if(Ship_info[i].missile_banks != NULL){
+			free(Ship_info[i].missile_banks);
+			Ship_info[i].missile_banks = NULL;
+		}
+	}
+	
+	// NOTE: pm->ship_bay is free'd is modelread.cpp, model_unload().
+
+		
 }	
 
 // -------------------------------------------------------------------------------------------------
Index: src/stats/medals.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/stats/medals.cpp,v
retrieving revision 1.9
diff -u -b -B -r1.9 medals.cpp
--- src/stats/medals.cpp	2003/06/03 04:00:40	1.9
+++ src/stats/medals.cpp	2003/06/08 15:50:33
@@ -924,6 +924,19 @@
 	palette_restore_palette();
 }
 
+// free up memory from table parsing
+void medal_tbl_close()
+{
+	int i;
+	
+	for (i=0; i<MAX_BADGES; i++) {
+		if (Badge_info[i].promotion_text) {
+			free(Badge_info[i].promotion_text);
+			Badge_info[i].promotion_text = NULL;
+		}
+	}
+}
+
 /*
 void init_medal_palette()
 {
Index: src/stats/scoring.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/stats/scoring.cpp,v
retrieving revision 1.4
diff -u -b -B -r1.4 scoring.cpp
--- src/stats/scoring.cpp	2003/05/25 02:30:44	1.4
+++ src/stats/scoring.cpp	2003/06/08 15:50:33
@@ -279,6 +279,19 @@
 	lcl_ext_close();
 }
 
+// free memory from table parsing
+void scoring_tbl_close()
+{
+	int i;
+	
+	for (i=0; i<NUM_RANKS; i++) {
+		if (Ranks[i].promotion_text) {
+			free(Ranks[i].promotion_text);
+			Ranks[i].promotion_text = NULL;
+		}
+	}
+}
+
 // initialize a nice blank scoring element
 void init_scoring_element(scoring_struct *s)
 {
Index: src/weapon/weapons.cpp
===================================================================
RCS file: /cvs/cvsroot/freespace2/src/weapon/weapons.cpp,v
retrieving revision 1.9
diff -u -b -B -r1.9 weapons.cpp
--- src/weapon/weapons.cpp	2003/05/25 02:30:44	1.9
+++ src/weapon/weapons.cpp	2003/06/08 15:50:35
@@ -3805,3 +3805,26 @@
 	best_lod = min(best_lod, wei->lod_count - 1);
 	return wei->lod[best_lod].bitmap_id;
 }
+
+// -------------------------------------------------------------------------------------------------
+// weapon_close()
+//
+// called in game_shutdown() to free malloced memory
+//
+// NOTE: do not call this function.  It is only called from game_shutdown()
+void weapon_close()
+{
+	int i;
+	
+	// free info from parsed table data
+	for (i=0; i<MAX_WEAPON_TYPES; i++) {
+		if ( Weapon_info[i].desc != NULL ) {
+			free(Weapon_info[i].desc);
+			Weapon_info[i].desc = NULL;
+		}
+		if ( Weapon_info[i].tech_desc != NULL ) {
+			free(Weapon_info[i].tech_desc);
+			Weapon_info[i].tech_desc = NULL;
+		}
+	}
+}


More information about the freespace2 mailing list