From 00a4c700d13719ac45c0405dc0edd2d0d2d61231 Mon Sep 17 00:00:00 2001 From: Martin Dvorak Date: Sat, 18 Aug 2018 08:38:56 +0200 Subject: [PATCH] Memleaks: down to 4 issues when non-interactive 1 history entry #68 --- src/hstr.c | 53 +++++++++++++++++++------------------- src/hstr_history.c | 31 +++++++++++++++------- src/include/hstr_history.h | 9 ++----- src/radixsort.c | 30 +++++++++++---------- 4 files changed, 67 insertions(+), 56 deletions(-) diff --git a/src/hstr.c b/src/hstr.c index 63ca8c5..d32c872 100644 --- a/src/hstr.c +++ b/src/hstr.c @@ -357,6 +357,31 @@ void hstr_init(void) =0; } +void hstr_destroy(void) +{ + favorites_destroy(hstr->favorites); + hstr_regexp_destroy(&hstr->regexp); + // blacklist is allocated by hstr struct + blacklist_destroy(&hstr->blacklist, false); + prioritized_history_destroy(hstr->history); + free(hstr); +} + +void hstr_on_exit(void) +{ + history_mgmt_flush(); + hstr_destroy(); +} + +void signal_callback_handler_ctrl_c(int signum) +{ + if(signum==SIGINT) { + hstr_curses_stop(false); + hstr_on_exit(); + exit(signum); + } +} + unsigned recalculate_max_history_items(void) { hstr->promptItems = getmaxy(stdscr) - 3; @@ -993,21 +1018,6 @@ void highlight_selection(int selectionCursorPosition, int previousSelectionCurso } } -void hstr_on_exit(void) -{ - history_mgmt_flush(); - free_prioritized_history(); -} - -void signal_callback_handler_ctrl_c(int signum) -{ - if(signum==SIGINT) { - hstr_curses_stop(false); - hstr_on_exit(); - exit(signum); - } -} - int remove_from_history_model(char* almostDead) { if(hstr->view==HH_VIEW_FAVORITES) { @@ -1463,7 +1473,7 @@ void hstr_assemble_cmdline_pattern(int argc, char* argv[], int startIndex) void hstr_interactive(void) { - hstr->history=get_prioritized_history(hstr->bigKeys, hstr->blacklist.set); + hstr->history=prioritized_history_create(hstr->bigKeys, hstr->blacklist.set); if(hstr->history) { history_mgmt_open(); if(hstr->interactive) { @@ -1529,15 +1539,6 @@ void hstr_getopt(int argc, char **argv) } } -void hstr_destroy(void) -{ - favorites_destroy(hstr->favorites); - hstr_regexp_destroy(&hstr->regexp); - // blacklist is allocated by hstr struct - blacklist_destroy(&hstr->blacklist, false); - free(hstr); -} - int hstr_main(int argc, char* argv[]) { setlocale(LC_ALL, ""); @@ -1550,7 +1551,7 @@ int hstr_main(int argc, char* argv[]) blacklist_load(&hstr->blacklist); hstr_interactive(); - hstr_destroy(); + // hstr cleanup is handled by hstr_on_exit() return EXIT_SUCCESS; } diff --git a/src/hstr_history.c b/src/hstr_history.c index e8e7a7a..83e3998 100644 --- a/src/hstr_history.c +++ b/src/hstr_history.c @@ -22,11 +22,11 @@ #include typedef struct { - char *item; + char* item; unsigned rank; } RankedHistoryItem; -static HistoryItems *prioritizedHistory; +static HistoryItems* prioritizedHistory; static bool dirty; #ifdef DEBUG_RADIX @@ -45,13 +45,17 @@ unsigned history_ranking_function(unsigned rank, int newOccurenceOrder, size_t l return metrics; } -char *get_history_file_name(void) +char* get_history_file_name(void) { - char *historyFile=getenv(ENV_VAR_HISTFILE); + char* historyFile = getenv(ENV_VAR_HISTFILE); if(!historyFile || strlen(historyFile)==0) { - char *home = getenv(ENV_VAR_HOME); + char* home = getenv(ENV_VAR_HOME); historyFile = malloc(strlen(home) + 1 + strlen(FILE_DEFAULT_HISTORY) + 1); strcat(strcat(strcpy(historyFile, home), "/"), FILE_DEFAULT_HISTORY); + } else { + // allocate so that this function always returns string to be freed + // (getenv() returns pointer (no need to free), home is allocated (must be freed) + historyFile = strdup(historyFile); } return historyFile; } @@ -88,7 +92,7 @@ bool is_hist_timestamp(const char* line) return (i >= 11); } -HistoryItems *get_prioritized_history(int optionBigKeys, HashSet *blacklist) +HistoryItems* prioritized_history_create(int optionBigKeys, HashSet *blacklist) { using_history(); @@ -97,6 +101,7 @@ HistoryItems *get_prioritized_history(int optionBigKeys, HashSet *blacklist) fprintf(stderr, "\nUnable to read history file from '%s'!\n",historyFile); exit(EXIT_FAILURE); } + free(historyFile); HISTORY_STATE* historyState=history_get_history_state(); bool isZsh = isZshParentShell(); @@ -171,6 +176,8 @@ HistoryItems *get_prioritized_history(int optionBigKeys, HashSet *blacklist) } } } + // TODO: history list entries + free(historyList); if(rawTimestamps) { rawOffset=0; for(i=0; ilength; i++) { @@ -207,6 +214,7 @@ HistoryItems *get_prioritized_history(int optionBigKeys, HashSet *blacklist) } free(prioritizedRadix[u]->data); free(prioritizedRadix[u]); + free(prioritizedRadix); } radixsort_destroy(&rs); @@ -221,10 +229,15 @@ HistoryItems *get_prioritized_history(int optionBigKeys, HashSet *blacklist) } -void free_prioritized_history(void) +void prioritized_history_destroy(HistoryItems* h) { - free(prioritizedHistory->items); - free(prioritizedHistory); + if(h->items) { + free(h->items); + } + if(h->rawItems) { + free(h->rawItems); + } + free(h); } void history_mgmt_open(void) diff --git a/src/include/hstr_history.h b/src/include/hstr_history.h index c403142..80ca7d1 100644 --- a/src/include/hstr_history.h +++ b/src/include/hstr_history.h @@ -46,13 +46,8 @@ typedef struct { unsigned rawCount; } HistoryItems; -HistoryItems* get_prioritized_history(int optionBigKeys, HashSet* blacklist); - -HistoryItems* get_history_items(void); -void free_history_items(void); - -HistoryItems* prioritize_history(HistoryItems* historyFileItems); -void free_prioritized_history(void); +HistoryItems* prioritized_history_create(int optionBigKeys, HashSet* blacklist); +void prioritized_history_destroy(HistoryItems* h); void history_mgmt_open(void); void history_clear_dirty(void); diff --git a/src/radixsort.c b/src/radixsort.c index b49a5eb..332f168 100644 --- a/src/radixsort.c +++ b/src/radixsort.c @@ -37,6 +37,22 @@ void radixsort_init(RadixSorter* rs, unsigned keyLimit) rs->_debug=RADIX_DEBUG_LEVEL_NONE; } +void radixsort_destroy(RadixSorter* rs) +{ + // radix items: DONE (passed on dump() by reference) + // rs: DONE (created and destroyed by caller) + // slots: + int topIndex = GET_TOP_INDEX(rs->maxKey); + do { + if(rs->topDigits[topIndex]) { + free(rs->topDigits[topIndex]); + free(rs->_slotDescriptors[topIndex]); + } + } while(--topIndex>=0); + free(rs->topDigits); + free(rs->_slotDescriptors); +} + void radixsort_set_debug_level(RadixSorter* rs, unsigned debugLevel) { rs->_debug=debugLevel; @@ -225,17 +241,3 @@ void radixsort_stat(RadixSorter* rs, bool listing) } fflush(stdout); } - -void radixsort_destroy(RadixSorter* rs) -{ - // radix items: DONE (passed on dump() by reference) - // rs: DONE (created and destroyed by caller) - // slots: - int topIndex = GET_TOP_INDEX(rs->maxKey); - do { - if(rs->topDigits[topIndex]) { - free(rs->topDigits[topIndex]); - free(rs->_slotDescriptors[topIndex]); - } - } while(--topIndex>=0); -}