From d569212ce5d0577c01b30796b288aafc2ae4fd9d Mon Sep 17 00:00:00 2001 From: frog Date: Mon, 14 Jun 2004 08:35:35 +0000 Subject: [PATCH] * Memory leak hunt with the following command: valgrind --leak-check=yes --leak-resolution=high --num-callers=40 --show-reachable=yes gdcmTests PrintDocument It looks like many (all?) leaks are due to the STL (or a bad usage of the STL. The lines producing the leaks now have a comment with a "MEMORY LEAK" tag: you can retrieve them with grep "MEMORY LEAK" src/* Here are two typical examples which I can't help fixing: ----- #include int main() { std::string name; char * test = "babo"; name = test; //// <--- valgrind detects 960 bytes lost in //// call to std::string::operator=(char const*) name.clear(); //// Doesn't help ! return 0; } ----- #include #include int main() { std::string line; std::cout << "Type a bunch of characters followed by RETURN: "; getline(std::cin, line); //// <--- valgrind dectects a loss //// of 1320 bytes in call to /// std::basic_istream<>& std::getline<> return 0; } ----- --- ChangeLog | 33 ++++++++++++ gdcmPython/gdcm.i | 126 +++++++++++++++++--------------------------- src/gdcmCommon.h | 2 +- src/gdcmDict.cxx | 18 +++---- src/gdcmDictSet.cxx | 3 +- src/gdcmSeqEntry.h | 30 +++++------ src/gdcmTS.cxx | 9 +--- 7 files changed, 105 insertions(+), 116 deletions(-) diff --git a/ChangeLog b/ChangeLog index 37ca0b88..4e508b88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2004-06-14 Eric Boix + * Memory leak hunt with the following command: + valgrind --leak-check=yes --leak-resolution=high --num-callers=40 + --show-reachable=yes gdcmTests PrintDocument + It looks like many (all?) leaks are due to the STL (or a bad usage + of the STL. The lines producing the leaks now have a comment with + a "MEMORY LEAK" tag: you can retrieve them with + grep "MEMORY LEAK" src/* + Here are two typical examples which I can't help fixing: + ----- + #include + int main() { + std::string name; + char * test = "babo"; + name = test; //// <--- valgrind detects 960 bytes lost in + //// call to std::string::operator=(char const*) + name.clear(); //// Doesn't help ! + return 0; + } + ----- + #include + #include + int main() { + std::string line; + std::cout << "Type a bunch of characters followed by RETURN: "; + getline(std::cin, line); //// <--- valgrind dectects a loss + //// of 1320 bytes in call to + /// std::basic_istream<>& std::getline<> + return 0; + } + ----- + + 2004-06-10 Eric Boix * src/gdcmHeader.[cxx|h]: - Predicates on the Transfer syntax (of the form Is[JPEF|RLE]*) diff --git a/gdcmPython/gdcm.i b/gdcmPython/gdcm.i index 9929125a..40b0ef9b 100644 --- a/gdcmPython/gdcm.i +++ b/gdcmPython/gdcm.i @@ -72,62 +72,68 @@ typedef unsigned int guint32; //////////////////////////////////////////////////////////////////////////// %typemap(out) std::list * { - PyObject* NewItem = (PyObject*)0; - PyObject* NewList = PyList_New(0); // The result of this typemap - for (std::list::iterator NewString = ($1)->begin(); - NewString != ($1)->end(); ++NewString) { - NewItem = PyString_FromString(NewString->c_str()); - PyList_Append( NewList, NewItem); - } - $result = NewList; + PyObject* NewItem = (PyObject*)0; + PyObject* NewList = PyList_New(0); // The result of this typemap + + for (std::list::iterator NewString = ($1)->begin(); + NewString != ($1)->end(); + ++NewString) + { + NewItem = PyString_FromString(NewString->c_str()); + PyList_Append( NewList, NewItem); + } + $result = NewList; } //////////////////////////////////////////////////////////////////////////// // Convert a c++ hash table in a python native dictionary %typemap(out) std::map > * { - PyObject* NewDict = PyDict_New(); // The result of this typemap - PyObject* NewKey = (PyObject*)0; - PyObject* NewVal = (PyObject*)0; - - for (std::map >::iterator tag = ($1)->begin(); - tag != ($1)->end(); ++tag) { + PyObject* NewDict = PyDict_New(); // The result of this typemap + PyObject* NewKey = (PyObject*)0; + PyObject* NewVal = (PyObject*)0; + + for (std::map >::iterator tag = ($1)->begin(); + tag != ($1)->end(); ++tag) + { std::string first = tag->first; // Do not publish entries whose keys is made of spaces if (first.length() == 0) continue; - NewKey = PyString_FromString(first.c_str()); - PyObject* NewList = PyList_New(0); - for (std::list::iterator Item = tag->second.begin(); - Item != tag->second.end(); ++Item) { - NewVal = PyString_FromString(Item->c_str()); - PyList_Append( NewList, NewVal); - } - PyDict_SetItem( NewDict, NewKey, NewList); - } - $result = NewDict; + NewKey = PyString_FromString(first.c_str()); + PyObject* NewList = PyList_New(0); + for (std::list::iterator Item = tag->second.begin(); + Item != tag->second.end(); + ++Item) + { + NewVal = PyString_FromString(Item->c_str()); + PyList_Append( NewList, NewVal); + } + PyDict_SetItem( NewDict, NewKey, NewList); + } + $result = NewDict; } //////////////////////////////////////////////////////////////////////////// // Convert a c++ hash table in a python native dictionary %typemap(out) TagDocEntryHT & { - PyObject* NewDict = PyDict_New(); // The result of this typemap - std::string RawName; // Element name as gotten from gdcm - PyObject* NewKey = (PyObject*)0; // Associated name as python object - std::string RawValue; // Element value as gotten from gdcm - PyObject* NewVal = (PyObject*)0; // Associated value as python object - - for (TagDocEntryHT::iterator tag = $1->begin(); tag != $1->end(); ++tag) { + PyObject* NewDict = PyDict_New(); // The result of this typemap + std::string RawName; // Element name as gotten from gdcm + PyObject* NewKey = (PyObject*)0; // Associated name as python object + std::string RawValue; // Element value as gotten from gdcm + PyObject* NewVal = (PyObject*)0; // Associated value as python object + + for (TagDocEntryHT::iterator tag = $1->begin(); tag != $1->end(); ++tag) + { + // The element name shall be the key: + RawName = tag->second->GetName(); + // gdcm unrecognized (including not loaded because their size exceeds + // the user specified treshold) elements are exported with their + // TagKey as key. + if (RawName == "Unknown") + RawName = tag->second->GetKey(); + NewKey = PyString_FromString(RawName.c_str()); - // The element name shall be the key: - RawName = tag->second->GetName(); - // gdcm unrecognized (including not loaded because their size exceeds - // the user specified treshold) elements are exported with their - // TagKey as key. - if (RawName == "Unknown") - RawName = tag->second->GetKey(); - NewKey = PyString_FromString(RawName.c_str()); - - // Element values are striped from leading/trailing spaces // Element values are striped from leading/trailing spaces if (gdcmValEntry* ValEntryPtr = dynamic_cast< gdcmValEntry* >(tag->second) ) @@ -138,49 +144,11 @@ typedef unsigned int guint32; continue; EatLeadingAndTrailingSpaces(RawValue); NewVal = PyString_FromString(RawValue.c_str()); - PyDict_SetItem( NewDict, NewKey, NewVal); } $result = NewDict; } -/* -CLEAN ME FIXME CLEANME TODO -%typemap(out) TagDocEntryHT { - PyObject* NewDict = PyDict_New(); // The result of this typemap - std::string RawName; // Element name as gotten from gdcm - PyObject* NewKey = (PyObject*)0; // Associated name as python object - std::string RawValue; // Element value as gotten from gdcm - PyObject* NewVal = (PyObject*)0; // Associated value as python object - - for (TagDocEntryHT::iterator tag = $1.begin(); tag != $1.end(); ++tag) { - - // The element name shall be the key: - RawName = tag->second->GetName(); - // gdcm unrecognized (including not loaded because their size exceeds - // the user specified treshold) elements are exported with their - // TagKey as key. - if (RawName == "Unknown") - RawName = tag->second->GetKey(); - NewKey = PyString_FromString(RawName.c_str()); - - // Element values are striped from leading/trailing spaces - if (gdcmValEntry* ValEntryPtr = - dynamic_cast< gdcmValEntry* >(tag->second) ) - { - RawValue = ValEntryPtr->GetValue(); - } - else - continue; - EatLeadingAndTrailingSpaces(RawValue); - NewVal = PyString_FromString(RawValue.c_str()); - - PyDict_SetItem( NewDict, NewKey, NewVal); - } - $result = NewDict; -} -*/ - //////////////////////////////////////////////////////////////////////////// %typemap(out) ListDicomDirPatient & { PyObject* NewItem = (PyObject*)0; diff --git a/src/gdcmCommon.h b/src/gdcmCommon.h index 4f9d4ece..46c3bc29 100644 --- a/src/gdcmCommon.h +++ b/src/gdcmCommon.h @@ -81,7 +81,7 @@ typedef int gint32; #include -const std::string GDCM_UNFOUND = "gdcm::Unfound"; +const std::string GDCM_UNFOUND = "gdcm::Unfound"; /// MEMORY LEAK typedef std::string TagKey; typedef std::string TagName; diff --git a/src/gdcmDict.cxx b/src/gdcmDict.cxx index 7d9585cd..46edb403 100644 --- a/src/gdcmDict.cxx +++ b/src/gdcmDict.cxx @@ -26,15 +26,12 @@ gdcmDict::gdcmDict(std::string & FileName) { FileName.c_str()); while (!from.eof()) { - from >> std::hex >> group >> element; - eatwhite(from); - from.getline(buff, 256, ' '); - vr = buff; - eatwhite(from); - from.getline(buff, 256, ' '); - fourth = buff; - from.getline(buff, 256, '\n'); - name = buff; + from >> std::hex; + from >> group; /// MEMORY LEAK in std::istream::operator>> + from >> element; + from >> vr; + from >> fourth; + getline(from, name); /// MEMORY LEAK in std::getline<> gdcmDictEntry * newEntry = new gdcmDictEntry(group, element, vr, fourth, name); @@ -135,7 +132,8 @@ bool gdcmDict::AddNewEntry(gdcmDictEntry *NewEntry) else { KeyHt[NewEntry->GetKey()] = NewEntry; - NameHt[NewEntry->GetName()] = NewEntry; + NameHt[NewEntry->GetName()] = NewEntry; /// MEMORY LEAK in + /// std::map<>::operator[] return(true); } } diff --git a/src/gdcmDictSet.cxx b/src/gdcmDictSet.cxx index 0a407bb4..882344ae 100644 --- a/src/gdcmDictSet.cxx +++ b/src/gdcmDictSet.cxx @@ -15,7 +15,8 @@ gdcmDictSet::gdcmDictSet(void) { DictPath = BuildDictPath(); - std::string PubDictFile = DictPath + PUB_DICT_FILENAME; + std::string PubDictFile(DictPath); + PubDictFile += PUB_DICT_FILENAME; /// MEMORY LEAK std::string::operator+= Dicts[PUB_DICT_NAME] = new gdcmDict(PubDictFile); } diff --git a/src/gdcmSeqEntry.h b/src/gdcmSeqEntry.h index e197bc04..143e382b 100644 --- a/src/gdcmSeqEntry.h +++ b/src/gdcmSeqEntry.h @@ -20,22 +20,19 @@ public: virtual void Print(std::ostream &os = std::cout); - /// \brief returns the SQITEM chained List for this SeQuence. - inline ListSQItem &GetSQItems() - {return items;}; + /// \brief returns the SQITEM chained List for this SeQuence. + inline ListSQItem &GetSQItems() {return items;}; - /// \brief Sets the delimitor mode - inline void SetDelimitorMode(bool dm) - { delimitor_mode = dm;} + /// \brief Sets the delimitor mode + inline void SetDelimitorMode(bool dm) { delimitor_mode = dm;} - /// \brief Sets the Sequence Delimitation Item - inline void SetSequenceDelimitationItem(gdcmDocEntry * e) - { seq_term = e;} + /// \brief Sets the Sequence Delimitation Item + inline void SetSequenceDelimitationItem(gdcmDocEntry * e) { seq_term = e;} - void AddEntry(gdcmSQItem *it); + void AddEntry(gdcmSQItem *it); - /// \brief creates a new SQITEM for this SeQuence. - gdcmSQItem * NewItem(void); + /// \brief creates a new SQITEM for this SeQuence. + gdcmSQItem * NewItem(void); gdcmDocEntry *NewDocEntryByNumber(guint16 group, guint16 element); gdcmDocEntry *NewDocEntryByName (std::string Name); @@ -46,21 +43,18 @@ public: protected: private: - // Variables -/// \brief If this Sequence is in delimitor mode (length =0xffffffff) or not + /// \brief If this Sequence is in delimitor mode (length =0xffffffff) or not bool delimitor_mode; -/// \brief chained list of SQ Items + /// \brief Chained list of SQ Items ListSQItem items; -/// \brief sequence terminator item + /// \brief sequence terminator item gdcmDocEntry *seq_term; - }; - //----------------------------------------------------------------------------- #endif diff --git a/src/gdcmTS.cxx b/src/gdcmTS.cxx index 0712d1db..e6543d8c 100644 --- a/src/gdcmTS.cxx +++ b/src/gdcmTS.cxx @@ -24,13 +24,8 @@ gdcmTS::gdcmTS(void) std::string name; while (!from.eof()) { - eatwhite(from); - from.getline(buff, 1024, ' '); - key = buff; - - eatwhite(from); - from.getline(buff, 1024, '\n'); - name = buff; + from >> key; + getline(from, name); /// MEMORY LEAK if(key!="") { -- 2.48.1