1
0
mirror of https://git.savannah.gnu.org/git/gperf.git synced 2025-12-02 21:19:24 +00:00

Fix memory leaks.

This commit is contained in:
Bruno Haible
2003-01-23 12:03:33 +00:00
parent 83440a2aed
commit a9916548fa
8 changed files with 141 additions and 60 deletions

View File

@@ -1,5 +1,20 @@
2002-11-10 Bruno Haible <bruno@clisp.org> 2002-11-10 Bruno Haible <bruno@clisp.org>
Fix memory leaks.
* src/keyword.h (empty_string): New declaration.
* src/keyword.cc (empty_string): New variable.
* src/input.h (Input::_input): Make public.
(Input::_input_end): New field.
* src/input.cc (read_input): When removing leading whitespace from
struct_decl, reallocate it. For rest, use empty_string instead of "".
Set _input_end.
(Input::~Input): Delete _struct_decl, _struct_tag, _return_type.
* src/search.cc (Search::prepare): When removing an element from
the keyword list, delete the list node.
(Search::~Search): Delete _occurrences, _asso_values.
* src/main.cc (main): Between Search::~Search and Input::~Input,
destroy the keyword list.
Rewrite the input routines. Rewrite the input routines.
* src/input.h: Don't include read-line.h. * src/input.h: Don't include read-line.h.
(Input): Don't inherit from class Read_Line. (Input): Don't inherit from class Read_Line.

View File

@@ -299,9 +299,19 @@ Input::read_input ()
if (struct_decl) if (struct_decl)
{ {
/* Drop leading whitespace. */ /* Drop leading whitespace. */
while (struct_decl[0] == '\n' || struct_decl[0] == ' ' {
|| struct_decl[0] == '\t') char *p = struct_decl;
struct_decl++; while (p[0] == '\n' || p[0] == ' ' || p[0] == '\t')
p++;
if (p != struct_decl)
{
size_t len = strlen (p);
char *new_struct_decl = new char[len + 1];
memcpy (new_struct_decl, p, len + 1);
delete[] struct_decl;
struct_decl = new_struct_decl;
}
}
/* Drop trailing whitespace. */ /* Drop trailing whitespace. */
for (char *p = struct_decl + strlen (struct_decl); p > struct_decl;) for (char *p = struct_decl + strlen (struct_decl); p > struct_decl;)
if (p[-1] == '\n' || p[-1] == ' ' || p[-1] == '\t') if (p[-1] == '\n' || p[-1] == ' ' || p[-1] == '\t')
@@ -315,7 +325,6 @@ Input::read_input ()
" for option --struct-type\n"); " for option --struct-type\n");
exit (1); exit (1);
} }
if (struct_decl)
{ {
/* Ensure trailing semicolon. */ /* Ensure trailing semicolon. */
size_t old_len = strlen (struct_decl); size_t old_len = strlen (struct_decl);
@@ -529,7 +538,7 @@ Input::read_input ()
rest = line_rest; rest = line_rest;
} }
else else
rest = ""; rest = empty_string;
} }
else else
{ {
@@ -541,7 +550,7 @@ Input::read_input ()
{ {
keyword = line; keyword = line;
keyword_length = lp - line; keyword_length = lp - line;
rest = ""; rest = empty_string;
break; break;
} }
if (strchr (delimiters, *lp) != NULL) if (strchr (delimiters, *lp) != NULL)
@@ -560,7 +569,7 @@ Input::read_input ()
rest = line_rest; rest = line_rest;
} }
else else
rest = ""; rest = empty_string;
break; break;
} }
lp++; lp++;
@@ -588,9 +597,14 @@ Input::read_input ()
/* To be freed in the destructor. */ /* To be freed in the destructor. */
_input = input; _input = input;
_input_end = input_end;
} }
Input::~Input () Input::~Input ()
{ {
/* Free allocated memory. */
delete[] _return_type;
delete[] _struct_tag;
delete[] _struct_decl;
delete[] _input; delete[] _input;
} }

View File

@@ -40,9 +40,10 @@ private:
FILE * _stream; FILE * _stream;
/* Creates the keywords. */ /* Creates the keywords. */
Keyword_Factory * const _factory; Keyword_Factory * const _factory;
public:
/* Memory block containing the entire input. */ /* Memory block containing the entire input. */
char * _input; char * _input;
public: char * _input_end;
/* The C code from the declarations section. */ /* The C code from the declarations section. */
const char * _verbatim_declarations; const char * _verbatim_declarations;
const char * _verbatim_declarations_end; const char * _verbatim_declarations_end;

View File

@@ -121,6 +121,11 @@ Keyword_Factory::~Keyword_Factory ()
} }
/* ------------------------------------------------------------------------- */
char empty_string[1] = "";
#ifndef __OPTIMIZE__ #ifndef __OPTIMIZE__
#define INLINE /* not inline */ #define INLINE /* not inline */

View File

@@ -91,6 +91,9 @@ public:
const char *rest) = 0; const char *rest) = 0;
}; };
/* A statically allocated empty string. */
extern char empty_string[1];
#ifdef __OPTIMIZE__ #ifdef __OPTIMIZE__
#define INLINE inline #define INLINE inline

View File

@@ -49,6 +49,8 @@ KeywordExt_Factory::create_keyword (const char *allchars, int allchars_length, c
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
int exitcode;
/* Set the Options. Open the input file and assign stdin to it. */ /* Set the Options. Open the input file and assign stdin to it. */
option.parse_options (argc, argv); option.parse_options (argc, argv);
@@ -61,6 +63,7 @@ main (int argc, char *argv[])
exit (1); exit (1);
} }
{
/* Initialize the keyword list. */ /* Initialize the keyword list. */
KeywordExt_Factory factory; KeywordExt_Factory factory;
Input inputter (stdin, &factory); Input inputter (stdin, &factory);
@@ -69,10 +72,13 @@ main (int argc, char *argv[])
elements were created by KeywordExt_Factory. */ elements were created by KeywordExt_Factory. */
KeywordExt_List* list = static_cast<KeywordExt_List*>(inputter._head); KeywordExt_List* list = static_cast<KeywordExt_List*>(inputter._head);
{
/* Search for a good hash function. */ /* Search for a good hash function. */
Search searcher (list); Search searcher (list);
searcher.optimize (); searcher.optimize ();
list = searcher._head;
{
/* Output the hash function code. */ /* Output the hash function code. */
Output outputter (searcher._head, Output outputter (searcher._head,
inputter._struct_decl, inputter._struct_decl,
@@ -94,13 +100,42 @@ main (int argc, char *argv[])
outputter.output (); outputter.output ();
/* Check for write error on stdout. */ /* Check for write error on stdout. */
int status = 0; exitcode = 0;
if (fflush (stdout) || ferror (stdout)) if (fflush (stdout) || ferror (stdout))
{ {
fprintf (stderr, "error while writing output file\n"); fprintf (stderr, "error while writing output file\n");
status = 1; exitcode = 1;
}
/* Here we run the Output destructor. */
}
/* Here we run the Search destructor. */
}
/* Also delete the list that was allocated inside Input and reordered
inside Search. */
for (KeywordExt_List *ptr = list; ptr; ptr = ptr->rest())
{
KeywordExt *keyword = ptr->first();
do
{
KeywordExt *next_keyword = keyword->_duplicate_link;
delete[] keyword->_selchars;
if (keyword->_rest != empty_string)
delete[] keyword->_rest;
if (!(keyword->_allchars >= inputter._input
&& keyword->_allchars < inputter._input_end))
delete[] keyword->_allchars;
delete keyword;
keyword = next_keyword;
}
while (keyword != NULL);
}
delete_list (list);
/* Here we run the Input destructor. */
} }
/* Don't use exit() here, it skips the destructors. */ /* Don't use exit() here, it skips the destructors. */
return status; return exitcode;
} }

View File

@@ -94,10 +94,11 @@ Search::prepare ()
Hash_Table representatives (_list_len, option[NOLENGTH]); Hash_Table representatives (_list_len, option[NOLENGTH]);
KeywordExt_List *prev = NULL; /* list node before temp */ KeywordExt_List *prev = NULL; /* list node before temp */
for (temp = _head; temp; temp = temp->rest()) for (temp = _head; temp; )
{ {
KeywordExt *keyword = temp->first(); KeywordExt *keyword = temp->first();
KeywordExt *other_keyword = representatives.insert (keyword); KeywordExt *other_keyword = representatives.insert (keyword);
KeywordExt_List *garbage = NULL;
if (other_keyword) if (other_keyword)
{ {
@@ -105,6 +106,7 @@ Search::prepare ()
_list_len--; _list_len--;
/* Remove keyword from the main list. */ /* Remove keyword from the main list. */
prev->rest() = temp->rest(); prev->rest() = temp->rest();
garbage = temp;
/* And insert it on other_keyword's duplicate list. */ /* And insert it on other_keyword's duplicate list. */
keyword->_duplicate_link = other_keyword->_duplicate_link; keyword->_duplicate_link = other_keyword->_duplicate_link;
other_keyword->_duplicate_link = keyword; other_keyword->_duplicate_link = keyword;
@@ -121,6 +123,9 @@ Search::prepare ()
keyword->_duplicate_link = NULL; keyword->_duplicate_link = NULL;
prev = temp; prev = temp;
} }
temp = temp->rest();
if (garbage)
delete garbage;
} }
} }
@@ -798,4 +803,6 @@ Search::~Search ()
fprintf (stderr, "End dumping list.\n\n"); fprintf (stderr, "End dumping list.\n\n");
} }
delete[] _asso_values;
delete[] _occurrences;
} }

View File

@@ -48,6 +48,7 @@ SHELL = /bin/sh
VPATH = $(srcdir) VPATH = $(srcdir)
GPERF = ../src/gperf GPERF = ../src/gperf
#GPERF = valgrind --num-callers=20 --leak-check=yes --leak-resolution=high --show-reachable=yes ../src/gperf
all : all :