From 18b6ac3369e6d703c3c305179b9f48a24ad16a8b Mon Sep 17 00:00:00 2001 From: Vladimir Weinstein Date: Mon, 26 Jun 2000 22:46:15 +0000 Subject: [PATCH] ICU-432 fixing leaks X-SVN-Rev: 1649 --- icu4c/source/common/rbdata.cpp | 1 + icu4c/source/common/resbund.cpp | 12 ++++++---- icu4c/source/common/uresbund.c | 2 +- icu4c/source/i18n/brkiter.cpp | 8 +++++++ icu4c/source/i18n/dcfmtsym.cpp | 3 +++ icu4c/source/i18n/mergecol.cpp | 39 +++++++++++++++++++++++++++++---- icu4c/source/i18n/tblcoll.cpp | 28 ++++++----------------- icu4c/source/i18n/timezone.cpp | 22 ++++++++++++++----- 8 files changed, 80 insertions(+), 35 deletions(-) diff --git a/icu4c/source/common/rbdata.cpp b/icu4c/source/common/rbdata.cpp index abe94dffc8c..9be638bfc7d 100644 --- a/icu4c/source/common/rbdata.cpp +++ b/icu4c/source/common/rbdata.cpp @@ -62,6 +62,7 @@ String2dList::~String2dList() for(int32_t i = 0; i < fRowCount; ++i) { delete[] fStrings[i]; } + delete[] fStrings; } const UnicodeString& diff --git a/icu4c/source/common/resbund.cpp b/icu4c/source/common/resbund.cpp index bef1e18e352..4098081f93f 100644 --- a/icu4c/source/common/resbund.cpp +++ b/icu4c/source/common/resbund.cpp @@ -375,7 +375,8 @@ void ResourceBundle::resetIterator(void) { } ResourceBundle ResourceBundle::getNext(UErrorCode& status) { - return ResourceBundle(ures_getNextResource(resource, 0, &status)); + UResourceBundle r; + return ResourceBundle(ures_getNextResource(resource, &r, &status)); } UnicodeString ResourceBundle::getNextString(UErrorCode& status) { @@ -391,7 +392,8 @@ UnicodeString ResourceBundle::getNextString(const char ** key, UErrorCode& statu } ResourceBundle ResourceBundle::get(int32_t indexR, UErrorCode& status) const { - return ResourceBundle(ures_getByIndex(resource, indexR, 0, &status)); + UResourceBundle r; + return ResourceBundle(ures_getByIndex(resource, indexR, &r, &status)); } UnicodeString ResourceBundle::getStringEx(int32_t indexS, UErrorCode& status) const { @@ -401,7 +403,8 @@ UnicodeString ResourceBundle::getStringEx(int32_t indexS, UErrorCode& status) co } ResourceBundle ResourceBundle::get(const char* key, UErrorCode& status) const { - return ResourceBundle(ures_getByKey(resource, key, 0, &status)); + UResourceBundle r; + return ResourceBundle(ures_getByKey(resource, key, &r, &status)); } UnicodeString ResourceBundle::getStringEx(const char* key, UErrorCode& status) const { @@ -522,7 +525,8 @@ ResourceBundle::get2dArray(const char *resourceTag, int32_t& columnCount, UErrorCode& err) const { - UnicodeString **result = 0; + //UnicodeString **result = 0; + UnicodeString **result; String2dList *sldata = 0; int32_t len=0; diff --git a/icu4c/source/common/uresbund.c b/icu4c/source/common/uresbund.c index 59900d0c021..cef5906f264 100644 --- a/icu4c/source/common/uresbund.c +++ b/icu4c/source/common/uresbund.c @@ -652,7 +652,7 @@ U_CAPI UResourceBundle* U_EXPORT2 ures_getNextResource(UResourceBundle *resB, UR case RES_INT: case RES_BINARY: case RES_STRING: - return copyResb(NULL, resB); + return copyResb(fillIn, resB); break; case RES_TABLE: r = res_getTableItemByIndex(&(resB->fResData), resB->fRes, resB->fIndex, &key); diff --git a/icu4c/source/i18n/brkiter.cpp b/icu4c/source/i18n/brkiter.cpp index d2713ac1e48..a520b9a56c4 100644 --- a/icu4c/source/i18n/brkiter.cpp +++ b/icu4c/source/i18n/brkiter.cpp @@ -75,6 +75,8 @@ BreakIterator::createWordInstance(const Locale& key, UErrorCode& status) } } + //udata_close(file); // This prevents a leak, but it should be checked whether it is harmful + return result; } @@ -119,6 +121,8 @@ BreakIterator::createLineInstance(const Locale& key, UErrorCode& status) } } + //udata_close(file); // This prevents a leak, but it should be checked whether it is harmful + return result; } @@ -145,6 +149,8 @@ BreakIterator::createCharacterInstance(const Locale& key, UErrorCode& status) } } + //udata_close(file); // This prevents a leak, but it should be checked whether it is harmful + return result; } @@ -171,6 +177,8 @@ BreakIterator::createSentenceInstance(const Locale& key, UErrorCode& status) } } + //udata_close(file); // This prevents a leak, but it should be checked whether it is harmful + return result; } diff --git a/icu4c/source/i18n/dcfmtsym.cpp b/icu4c/source/i18n/dcfmtsym.cpp index 65268803e45..9a331ed5dcb 100644 --- a/icu4c/source/i18n/dcfmtsym.cpp +++ b/icu4c/source/i18n/dcfmtsym.cpp @@ -140,6 +140,9 @@ DecimalFormatSymbols::initialize(const Locale& locale, UErrorCode& status, } initialize(numberElements, currencyElements); + + delete[] numberElements; + delete[] currencyElements; } // Initializes the DecimalFormatSymbol instance with the data obtained diff --git a/icu4c/source/i18n/mergecol.cpp b/icu4c/source/i18n/mergecol.cpp index b3e91948d61..219152e94ac 100644 --- a/icu4c/source/i18n/mergecol.cpp +++ b/icu4c/source/i18n/mergecol.cpp @@ -79,6 +79,7 @@ MergeCollation::MergeCollation(const UnicodeString& pattern, } setPattern(pattern, decompMode, status); + if (U_FAILURE(status)) { delete [] statusArray; @@ -112,6 +113,13 @@ MergeCollation::operator=(const MergeCollation& other) if (this != &other) { *patterns = *other.patterns; + + if(lastEntry != 0) { + if (lastEntry->strength == PatternEntry::RESET) { + delete lastEntry; + } + } + lastEntry = 0; saveEntry = 0; @@ -130,6 +138,12 @@ MergeCollation::operator=(const MergeCollation& other) */ MergeCollation::~MergeCollation() { + if(lastEntry != 0) { + if (lastEntry->strength == PatternEntry::RESET) { + delete lastEntry; + } + } + delete patterns; delete [] statusArray; } @@ -294,7 +308,14 @@ void MergeCollation::addPattern(const UnicodeString& pattern, } entry = parser->next(success); + + if (entry == (PatternEntry *)0x032ac2c0) + { + int i=0; + } } + // WEIV tentatively - is there a leak at the end??? + delete parser; } /** @@ -407,6 +428,11 @@ void MergeCollation::fixEntry(PatternEntry* newEntry, newEntry->extension.insert(0, excess); if (lastIndex != patterns->size()) { + if(lastEntry != 0) { + if (lastEntry->strength == PatternEntry::RESET) { + delete lastEntry; + } + } lastEntry = saveEntry; changeLastEntry = FALSE; } @@ -422,13 +448,18 @@ void MergeCollation::fixEntry(PatternEntry* newEntry, else { patterns->atInsert(lastIndex, newEntry); // add at end - } } + } if (changeLastEntry) - { - lastEntry = newEntry; - } + { + if(lastEntry != 0) { + if (lastEntry->strength == PatternEntry::RESET) { + delete lastEntry; + } + } + lastEntry = newEntry; + } } int32_t diff --git a/icu4c/source/i18n/tblcoll.cpp b/icu4c/source/i18n/tblcoll.cpp index 4f04859ff14..bbc912bdda9 100644 --- a/icu4c/source/i18n/tblcoll.cpp +++ b/icu4c/source/i18n/tblcoll.cpp @@ -934,10 +934,10 @@ RuleBasedCollator::constructFromFile( const Locale& locale, data = 0; } - char *binaryFilePath = createPathName(UnicodeString(u_getDataDirectory(),""), - localeFileName, UnicodeString(kFilenameSuffix,"")); - if(tryBinaryFile) { + char *binaryFilePath = createPathName(UnicodeString(u_getDataDirectory(),""), + localeFileName, UnicodeString(kFilenameSuffix,"")); + // Try to load up the collation from a binary file first constructFromFile(binaryFilePath, status); #ifdef COLLDEBUG @@ -950,6 +950,7 @@ RuleBasedCollator::constructFromFile( const Locale& locale, if(status == U_FILE_ACCESS_ERROR) { status = U_ZERO_ERROR; } + delete [] binaryFilePath; } // Now try to load it up from a resource bundle text source file @@ -965,7 +966,6 @@ RuleBasedCollator::constructFromFile( const Locale& locale, // if there is no resource bundle file for the give locale, break out if(U_FAILURE(status)) { - delete [] binaryFilePath; return; } @@ -986,14 +986,12 @@ RuleBasedCollator::constructFromFile( const Locale& locale, if(colString.isBogus()) { status = U_MEMORY_ALLOCATION_ERROR; - delete [] binaryFilePath; return; } // if this bundle doesn't contain collation data, break out if(U_FAILURE(intStatus)) { status = U_MISSING_RESOURCE_ERROR; - delete [] binaryFilePath; return; } @@ -1004,14 +1002,12 @@ RuleBasedCollator::constructFromFile( const Locale& locale, colString.insert(0, DEFAULTRULES); if(colString.isBogus()) { status = U_MEMORY_ALLOCATION_ERROR; - delete [] binaryFilePath; return; } constructFromRules(colString, intStatus); if(intStatus == U_MEMORY_ALLOCATION_ERROR) { status = U_MEMORY_ALLOCATION_ERROR; - delete [] binaryFilePath; return; } @@ -1029,19 +1025,7 @@ RuleBasedCollator::constructFromFile( const Locale& locale, #ifdef COLLDEBUG cerr << localeFileName << " ascii load " << (U_SUCCESS(status) ? "OK" : "Failed") << " - try= " << (tryBinaryFile?"true":"false") << endl; #endif - - if(U_SUCCESS(status) && tryBinaryFile) { - // If we get a RuleBasedCollator result, even if it is derived - // from a default or a fallback, then we write it out as a - // binary file to the disk. The next time the system wants to - // get this collation, it will load up very quickly from the - // binary file. - /*UBool ok = writeToFile(binaryFilePath);*/ /*!*/ - delete [] binaryFilePath; -#ifdef COLLDEBUG - cerr << localeFileName << " binary write " << (ok? "OK" : "Failed") << endl; -#endif - } + } RuleBasedCollator::~RuleBasedCollator() @@ -1137,6 +1121,8 @@ RuleBasedCollator::getRules() const // the rules from. Therefore, we fetch the rules off the disk. // Notice that we pass in a tryBinaryFile value of FALSE, since // by design the binary file has NO rules in it! + //UErrorCode status = U_ZERO_ERROR; + //RuleBasedCollator temp(data->realLocaleName, status); RuleBasedCollator temp; UErrorCode status = U_ZERO_ERROR; temp.constructFromFile(data->desiredLocale, data->realLocaleName, FALSE, status); diff --git a/icu4c/source/i18n/timezone.cpp b/icu4c/source/i18n/timezone.cpp index 229d1df082e..d38da89d5df 100644 --- a/icu4c/source/i18n/timezone.cpp +++ b/icu4c/source/i18n/timezone.cpp @@ -64,6 +64,7 @@ const uint32_t* TimeZone::INDEX_BY_ID = 0; const OffsetIndex* TimeZone::INDEX_BY_OFFSET = 0; UnicodeString* TimeZone::ZONE_IDS = 0; UBool TimeZone::DATA_LOADED = FALSE; +UDataMemory* TimeZone::UDATA_POINTER = 0; UMTX TimeZone::LOCK; /** @@ -84,8 +85,9 @@ void TimeZone::loadZoneData() { Mutex lock(&LOCK); if (!DATA_LOADED) { UErrorCode status = U_ZERO_ERROR; - UDataMemory *data = udata_openChoice(0, TZ_DATA_TYPE, TZ_DATA_NAME, - isDataAcceptable, 0, &status); + UDATA_POINTER = udata_openChoice(0, TZ_DATA_TYPE, TZ_DATA_NAME, // THIS IS NOT A LEAK! + isDataAcceptable, 0, &status); // see the comment on udata_close line + UDataMemory *data = UDATA_POINTER; if (U_SUCCESS(status)) { DATA = (TZHeader*)udata_getMemory(data); // Result guaranteed to be nonzero if data is nonzero @@ -119,6 +121,10 @@ void TimeZone::loadZoneData() { name += uprv_strlen(name) + 1; } } + //udata_close(data); // Without udata_close purify will report a leak. However, DATA_LOADED is + // static, and udata_openChoice will be called only once, and data from + // udata_openChoice needs to stick around. + } // Whether we succeed or fail, stop future attempts @@ -573,7 +579,10 @@ TimeZone::createCustomTimeZone(const UnicodeString& id) Formattable n(kParseFailed); numberFormat->parse(id, n, pos); - if (pos.getIndex() == start) return 0; + if (pos.getIndex() == start) { + delete numberFormat; + return 0; + } offset = n.getLong(); if (pos.getIndex() < id.length() && @@ -585,7 +594,10 @@ TimeZone::createCustomTimeZone(const UnicodeString& id) int32_t oldPos = pos.getIndex(); n.setLong(kParseFailed); numberFormat->parse(id, n, pos); - if (pos.getIndex() == oldPos) return 0; + if (pos.getIndex() == oldPos) { + delete numberFormat; + return 0; + } offset += n.getLong(); } else @@ -605,8 +617,8 @@ TimeZone::createCustomTimeZone(const UnicodeString& id) if(negative) offset = -offset; - return new SimpleTimeZone(offset * 60000, CUSTOM_ID); delete numberFormat; + return new SimpleTimeZone(offset * 60000, CUSTOM_ID); } return 0; }