From 010e6781623d5c02003b6ff986c0ccecef322f95 Mon Sep 17 00:00:00 2001 From: chaukap Date: Mon, 17 Jun 2019 14:06:32 -0600 Subject: [PATCH] Sealed up memory leaks This commit overhauls deallocation in both gridded and non-gridded modes. In ST_main.c * Added a boolean parameter to deallocate_Globals. * Wrapped some of the variables in an if statement dependent on the parameter. I did this because in gridded mode these pointers do not allocate any memory, but in non-gridded mode they do. In sxw.c: * Removed free_sxw_memory, _deallocate_memory, and load_sxw_memory * I removed free_sxw_memory because it overcomplicated the code. It's only call was in free_all_sxw_memory, so I combined them to make the code more readable. * I removed load_sxw_memory because it is depreciated, and referenced free_sxw_memory which I had already deleted. * I removed _deallocate_memory because it was redundant and unused. * In free_all_sxw_memory I went through each struct and deallocated every pointer to ensure no memory is leaked. * I did NOT delete SXW->f_files because it is never actually allocated memory. The previous call to Mem_Free(SXW->f_files.in) worked because it pointed to another variable which is allocated, but calling the function multiple times in gridded mode revealed that it is unnecessary. In ST_grid.c: * Added a few additional pointers to _free_grid_memory. * Added a loop which loads in a cell, then calls the non-gridded mode deallocation function. This reduces code reuse. --- ST_grid.c | 12 ++++++++- ST_main.c | 19 ++++++++------ sxw.c | 76 ++++++++++++++----------------------------------------- 3 files changed, 41 insertions(+), 66 deletions(-) diff --git a/ST_grid.c b/ST_grid.c index f6e7536b..1cb57e1f 100644 --- a/ST_grid.c +++ b/ST_grid.c @@ -326,7 +326,7 @@ void parm_free_memory(void); //from ST_main.c void Plot_Initialize(void); -void deallocate_Globals(void); +void deallocate_Globals(Bool isGriddedMode); //functions from ST_stats.c void stat_Collect(Int year); @@ -1646,10 +1646,20 @@ static void _free_grid_memory(void) for(i = 0; i < grid_Rows; ++i){ for(j = 0; j < grid_Cols; ++j){ Mem_Free(gridCells[i][j].mySpeciesInit.species_seed_avail); + Mem_Free(gridCells[i][j].mySeedDispersal->prob); + Mem_Free(gridCells[i][j].mySeedDispersal); Mem_Free(gridCells[i][j].someKillage); Mem_Free(gridCells[i][j].mySoils.lyr); + + /* Use deallocate_Globals from ST_main to deallocate global variables, + and free_all_sxw_memory from sxw to deallocate SXW variables. */ + load_cell(i,j); + deallocate_Globals(TRUE); + free_all_sxw_memory(); + unload_cell(); } } + for(i = 0; i < grid_Rows; ++i){ Mem_Free(gridCells[i]); } diff --git a/ST_main.c b/ST_main.c index bf7b6399..3b953f09 100644 --- a/ST_main.c +++ b/ST_main.c @@ -92,7 +92,7 @@ extern Bool* _SomeKillage; /***********************************************************/ void Plot_Initialize( void); void allocate_Globals(void); -void deallocate_Globals(void); +void deallocate_Globals(Bool isGriddedMode); static void usage(void) { char *s ="STEPPE plant community dynamics (SGS-LTER Jan-04).\n" @@ -329,7 +329,7 @@ int main(int argc, char **argv) { SW_CTL_clear_model(TRUE); // de-allocate all memory free_all_sxw_memory(); - deallocate_Globals(); + deallocate_Globals(FALSE); printf("\nend program\n"); fprintf(progfp, "\n"); @@ -424,15 +424,18 @@ void allocate_Globals(void){ } /* Deallocates the global variables */ -void deallocate_Globals(void){ +void deallocate_Globals(Bool isGriddedMode){ GrpIndex rg; SppIndex sp; - Mem_Free(Env); - Mem_Free(Succulent); - Mem_Free(Globals); - Mem_Free(Plot); - Mem_Free(_SomeKillage); + if(!isGriddedMode){ + Mem_Free(Env); + Mem_Free(Succulent); + Mem_Free(Globals); + Mem_Free(Plot); + Mem_Free(_SomeKillage); + } + /* Free Species */ ForEachSpecies(sp){ /* Start by freeing any pointers in the Species struct */ diff --git a/sxw.c b/sxw.c index 9407c988..5167001d 100644 --- a/sxw.c +++ b/sxw.c @@ -136,11 +136,7 @@ static void _make_swc_array(void); static void SXW_SW_Setup_Echo(void); static void SXW_Reinit(char* SOILWAT_file); -//these last four functions are to be used in ST_grid.c -void load_sxw_memory( RealD * grid_roots_max, RealD* grid_rootsXphen, RealD* grid_roots_active, RealD* grid_roots_active_rel, RealD* grid_roots_active_sum, RealD* grid_phen, RealD* grid_prod_bmass, RealD* grid_prod_pctlive ); void save_sxw_memory( RealD * grid_roots_max, RealD* grid_rootsXphen, RealD* grid_roots_active, RealD* grid_roots_active_rel, RealD* grid_roots_active_sum, RealD* grid_phen, RealD* grid_prod_bmass, RealD* grid_prod_pctlive ); -void free_sxw_memory( void ); -void _deallocate_memory(void); SXW_t* getSXW(void); SXW_resourceType* getSXWResources(void); transp_t* getTranspWindow(void); @@ -449,18 +445,6 @@ transp_t* getTranspWindow(void){ return transp_window; } -/* Deallocate any sxw local pointers. When running the non-gridded mode - * there is no need to call this since we only have one transp_window variable */ -void _deallocate_memory(void){ - Mem_Free(transp_window->ratios); - Mem_Free(transp_window->transp); - Mem_Free(transp_window->SoS_array); - Mem_Free(transp_window); - - Mem_Free(SXW); - Mem_Free(SXWResources); -} - /* Shallow copy variables into the local sxw variables. */ void copy_sxw_variables(SXW_t* newSXW, SXW_resourceType* newSXWResources, transp_t* newTransp_window){ SXW = newSXW; @@ -1139,26 +1123,13 @@ int getNTranspLayers(int veg_prod_type) { void free_all_sxw_memory( void ) { int k; - free_sxw_memory(); - Mem_Free(SXW->f_files); - Mem_Free(SXW->f_roots); - Mem_Free(SXW->f_phen); - Mem_Free(SXW->f_bvt); - Mem_Free(SXW->f_prod); - Mem_Free(SXW->f_watin); - - Mem_Free(SXW->transpTotal); - ForEachVegType(k) { - Mem_Free(SXW->transpVeg[k]); - } - - //Mem_Free(SXW->sum_dSWA_repartitioned); // required for `_SWA_contribution_by_group` - - Mem_Free(SXW->swc); -} + /* Free transp_window */ + Mem_Free(transp_window->ratios); + Mem_Free(transp_window->transp); + Mem_Free(transp_window->SoS_array); + Mem_Free(transp_window); -/***********************************************************/ -void free_sxw_memory( void ) { + /* Free SXWResources memory */ Mem_Free(SXWResources->_roots_max); Mem_Free(SXWResources->_rootsXphen); Mem_Free(SXWResources->_roots_active); @@ -1167,29 +1138,20 @@ void free_sxw_memory( void ) { Mem_Free(SXWResources->_phen); Mem_Free(SXWResources->_prod_bmass); Mem_Free(SXWResources->_prod_pctlive); -} + Mem_Free(SXWResources); -/***********************************************************/ -void load_sxw_memory( RealD* grid_roots_max, RealD* grid_rootsXphen, RealD* grid_roots_active, RealD* grid_roots_active_rel, RealD* grid_roots_active_sum, RealD* grid_phen, RealD* grid_prod_bmass, RealD* grid_prod_pctlive ) { - //load memory from the grid - free_sxw_memory(); - SXWResources->_roots_max = Mem_Calloc(SXW->NGrps * SXW->NTrLyrs, sizeof(RealD), "load_sxw_memory()"); - SXWResources->_rootsXphen = Mem_Calloc(SXW->NGrps * SXW->NPds * SXW->NTrLyrs, sizeof(RealD), "load_sxw_memory()"); - SXWResources->_roots_active = Mem_Calloc(SXW->NGrps * SXW->NPds * SXW->NTrLyrs, sizeof(RealD), "load_sxw_memory()"); - SXWResources->_roots_active_rel = Mem_Calloc(SXW->NGrps * SXW->NPds * SXW->NTrLyrs, sizeof(RealD), "load_sxw_memory()"); - SXWResources->_roots_active_sum = Mem_Calloc(4 * SXW->NPds * SXW->NTrLyrs, sizeof(RealD), "load_sxw_memory()"); - SXWResources->_phen = Mem_Calloc(SXW->NGrps * MAX_MONTHS, sizeof(RealD), "load_sxw_memory()"); - SXWResources->_prod_bmass = Mem_Calloc(SXW->NGrps * MAX_MONTHS, sizeof(RealD), "load_sxw_memory()"); - SXWResources->_prod_pctlive = Mem_Calloc(SXW->NGrps * MAX_MONTHS, sizeof(RealD), "load_sxw_memory()"); - - memcpy(SXWResources->_roots_max, grid_roots_max, SXW->NGrps * SXW->NTrLyrs * sizeof(RealD)); - memcpy(SXWResources->_rootsXphen, grid_rootsXphen, SXW->NGrps * SXW->NPds * SXW->NTrLyrs * sizeof(RealD)); - memcpy(SXWResources->_roots_active, grid_roots_active, SXW->NGrps * SXW->NPds * SXW->NTrLyrs * sizeof(RealD)); - memcpy(SXWResources->_roots_active_rel, grid_roots_active_rel, SXW->NGrps * SXW->NPds * SXW->NTrLyrs * sizeof(RealD)); - memcpy(SXWResources->_roots_active_sum, grid_roots_active_sum, 4 * SXW->NPds * SXW->NTrLyrs * sizeof(RealD)); - memcpy(SXWResources->_phen, grid_phen, SXW->NGrps * MAX_MONTHS * sizeof(RealD)); - memcpy(SXWResources->_prod_bmass, grid_prod_bmass, SXW->NGrps * MAX_MONTHS * sizeof(RealD)); - memcpy(SXWResources->_prod_pctlive, grid_prod_pctlive, SXW->NGrps * MAX_MONTHS * sizeof(RealD)); + /* Free SXW */ + Mem_Free(SXW->f_roots); + Mem_Free(SXW->f_phen); + Mem_Free(SXW->f_bvt); + Mem_Free(SXW->f_prod); + Mem_Free(SXW->f_watin); + Mem_Free(SXW->transpTotal); + ForEachVegType(k) { + Mem_Free(SXW->transpVeg[k]); + } + Mem_Free(SXW->swc); + Mem_Free(SXW); } /***********************************************************/