From 6b5dcfe0005f2a725fd721fe10abd1c3259e25ad Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 5 Aug 2021 15:53:09 +0300 Subject: [PATCH] Suppress memory leak when using Kernel_Utils::decode() + some code cleanup --- src/PluginUtils/GeomSelectionTools.h | 3 - src/SMESH/MG_ADAPT.cxx | 187 ++++++++++++++------------- src/SMESH/SMESH_Gen.cxx | 12 +- src/SMESHUtils/SMESH_File.cxx | 6 +- src/SMESHUtils/SMESH_TypeDefs.hxx | 2 + src/SMESH_I/SMESH_Gen_i.cxx | 14 +- 6 files changed, 110 insertions(+), 114 deletions(-) diff --git a/src/PluginUtils/GeomSelectionTools.h b/src/PluginUtils/GeomSelectionTools.h index 56b3c65a5..e1b8c741e 100644 --- a/src/PluginUtils/GeomSelectionTools.h +++ b/src/PluginUtils/GeomSelectionTools.h @@ -41,9 +41,6 @@ class LightApp_SelectionMgr; /*! * The GeomSelectionTools class gives high level tools to select Geom (and other objects) * A specific attention has been given to analyze selected GEOM objects. - * - * @param myStudy This class is specific to the study ! - * */ class PLUGINUTILS_EXPORT GeomSelectionTools diff --git a/src/SMESH/MG_ADAPT.cxx b/src/SMESH/MG_ADAPT.cxx index f3ea564e5..3530fe477 100644 --- a/src/SMESH/MG_ADAPT.cxx +++ b/src/SMESH/MG_ADAPT.cxx @@ -48,11 +48,12 @@ static std::string removeFile(std::string fileName, int& notOk) std::string errStr; notOk = std::remove(fileName.c_str()); if (notOk) errStr = ToComment("\n error while removing file : ") << fileName; - else errStr = ToComment("\n file : ") << fileName << " succesfully deleted! \n "; + else errStr = ToComment("\n file : ") << fileName << " succesfully deleted! \n "; return errStr; } -std::string MG_ADAPT::remove_extension(const std::string& filename) { +std::string MG_ADAPT::remove_extension(const std::string& filename) +{ size_t lastdot = filename.find_last_of("."); if (lastdot == std::string::npos) return filename; return filename.substr(0, lastdot); @@ -65,104 +66,103 @@ namespace return SMESH_File( fName ).exists(); } -// ======================================================================= -med_idt openMedFile(const std::string aFile) -// ======================================================================= -// renvoie le medId associe au fichier Med apres ouverture -{ - med_idt medIdt = MEDfileOpen(aFile.c_str(),MED_ACC_RDONLY); - if (medIdt <0) + // ======================================================================= + med_idt openMedFile(const std::string aFile) + // ======================================================================= + // renvoie le medId associe au fichier Med apres ouverture { - THROW_SALOME_EXCEPTION("\nThe med file " << aFile << " cannot be opened.\n"); + med_idt medIdt = MEDfileOpen(aFile.c_str(),MED_ACC_RDONLY); + if (medIdt <0) + { + THROW_SALOME_EXCEPTION("\nThe med file " << aFile << " cannot be opened.\n"); + } + return medIdt; } - return medIdt; -} - -// ======================================================================= -void getTimeStepInfos(std::string aFile, med_int& numdt, med_int& numit, std::string fieldName) -// ======================================================================= -{ -// Il faut voir si plusieurs maillages - - herr_t erreur = 0 ; - med_idt medIdt ; - - - // Ouverture du fichier - //~SCRUTE(aFile.toStdString()); - medIdt = openMedFile(aFile); - if ( medIdt < 0 ) return ; - // Lecture du nombre de champs - med_int ncha = MEDnField(medIdt) ; - if (ncha < 1 ) - { - //~addMessage( ToComment(" error: there is no field in ") << aFile, /*fatal=*/true ); - return; - } - // Lecture des caracteristiques du champs - - // Lecture du type du champ, des noms des composantes et du nom de l'unite - char nomcha [MED_NAME_SIZE+1]; - strcpy(nomcha, fieldName.c_str()); -// Lecture du nombre de composantes - med_int ncomp = MEDfieldnComponentByName(medIdt, nomcha); - char meshname[MED_NAME_SIZE+1]; - char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1); - char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1); - char dtunit[MED_SNAME_SIZE+1]; - med_bool local; - med_field_type typcha; - med_int nbofcstp; - erreur = MEDfieldInfoByName (medIdt, nomcha, meshname,&local,&typcha,comp,unit,dtunit, &nbofcstp); - free(comp); - free(unit); - if ( erreur < 0 ) + // ======================================================================= + void getTimeStepInfos(std::string aFile, med_int& numdt, med_int& numit, std::string fieldName) + // ======================================================================= { + // Il faut voir si plusieurs maillages + + herr_t erreur = 0 ; + med_idt medIdt ; + + // Ouverture du fichier + //~SCRUTE(aFile.toStdString()); + medIdt = openMedFile(aFile); + if ( medIdt < 0 ) return ; + // Lecture du nombre de champs + med_int ncha = MEDnField(medIdt) ; + if (ncha < 1 ) + { + //~addMessage( ToComment(" error: there is no field in ") << aFile, /*fatal=*/true ); + return; + } + // Lecture des caracteristiques du champs + + // Lecture du type du champ, des noms des composantes et du nom de l'unite + char nomcha [MED_NAME_SIZE+1]; + strcpy(nomcha, fieldName.c_str()); + // Lecture du nombre de composantes + med_int ncomp = MEDfieldnComponentByName(medIdt, nomcha); + char meshname[MED_NAME_SIZE+1]; + char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1); + char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1); + char dtunit[MED_SNAME_SIZE+1]; + med_bool local; + med_field_type typcha; + med_int nbofcstp; + erreur = MEDfieldInfoByName (medIdt, nomcha, meshname,&local,&typcha,comp,unit,dtunit, &nbofcstp); + free(comp); + free(unit); + if ( erreur < 0 ) + { //~addMessage( ToComment(" error: error while reading field ") << nomcha << " in file " << aFile , /*fatal=*/true ); - return; - } + return; + } - med_float dt; - med_int tmp_numdt, tmp_numit; + med_float dt; + med_int tmp_numdt, tmp_numit; - //~med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1; - //~myPrint("step ", step); - erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, 1, &numdt, &numit, &dt ); - for( int step = 1; step <= nbofcstp; step++ ) - { - erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, step, &tmp_numdt, &tmp_numit, &dt ); - if(tmp_numdt > numdt) + //~med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1; + //~myPrint("step ", step); + erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, 1, &numdt, &numit, &dt ); + for( int step = 1; step <= nbofcstp; step++ ) { - numdt = tmp_numdt; - numit = tmp_numit; + erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, step, &tmp_numdt, &tmp_numit, &dt ); + if(tmp_numdt > numdt) + { + numdt = tmp_numdt; + numit = tmp_numit; + } + } + if ( erreur < 0 ) + { + //~addMessage( ToComment(" error: error while reading field ") << nomcha << "step (numdt, numit) = " <<"("<< numdt<< ", " + //numit<< ")" <<" in file " << aFile , /*fatal=*/true ); + return; } - } - if ( erreur < 0 ) - { - //~addMessage( ToComment(" error: error while reading field ") << nomcha << "step (numdt, numit) = " <<"("<< numdt<< ", " - //numit<< ")" <<" in file " << aFile , /*fatal=*/true ); - return; - } - // Fermeture du fichier - if ( medIdt > 0 ) MEDfileClose(medIdt); + // Fermeture du fichier + if ( medIdt > 0 ) MEDfileClose(medIdt); -} - -struct GET_DEFAULT // struct used to get default value from GetOptionValue() -{ - bool isDefault; - operator bool* () { - return &isDefault; } -}; -class outFileStream : public std::ofstream{ -public: + struct GET_DEFAULT // struct used to get default value from GetOptionValue() + { + bool isDefault; + operator bool* () { + return &isDefault; + } + }; + + class outFileStream : public std::ofstream{ + public: ~outFileStream(){close();} //to close file at dtor -}; -} + }; + +} // anonymous namespace //---------------------------------------------------------------------------------------- MgAdapt::MgAdapt() @@ -863,14 +863,15 @@ void MgAdapt::execCmd( const char* cmd, int& err) } std::ostream logStream(buf); - + #if defined(WIN32) -#if defined(UNICODE) +# if defined(UNICODE) const wchar_t * aCmd = Kernel_Utils::utf8_decode(cmd); + SMESHUtils::ArrayDeleter deleter( aCmd ); std::unique_ptr pipe(_wpopen(aCmd, O_RDONLY), _pclose ); -#else +# else std::unique_ptr pipe(_popen(cmd, "r"), _pclose ); -#endif +# endif #else std::unique_ptr pipe(popen(cmd, "r"), pclose ); #endif @@ -961,12 +962,12 @@ std::string MgAdapt::getCommandToRun() } //~else //~{ - //~// constant value TODO + //~// constant value TODO //~} // Check coherence between mesh dimension and option fo adaptation checkDimensionOptionAdaptation(); -// sizemap file is written only if level is higher than 3 + // sizemap file is written only if level is higher than 3 if ( verbosityLevel > 3) { std::string solFileOut = getFileName()+".sol"; @@ -1357,7 +1358,7 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes(); MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file! if (meshNameOut =="") - meshNameOut = fileMesh->getName(); + meshNameOut = fileMesh->getName(); storeGroupsAndFams(fileMesh); MEDCoupling::MCAuto fields = MEDCoupling::MEDFileFields::New(); diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 399cef529..65e59d98d 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -1077,18 +1077,14 @@ std::vector< std::string > SMESH_Gen::GetPluginXMLPaths() xmlPath += sep + plugin + ".xml"; bool fileOK; #ifdef WIN32 - #ifdef UNICODE +# ifdef UNICODE const wchar_t* path = Kernel_Utils::decode_s(xmlPath); - #else + SMESHUtils::ArrayDeleter deleter( path ); +# else const char* path = xmlPath.c_str(); - #endif - +# endif fileOK = (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES); - #ifdef UNICODE - delete path; - #endif - #else fileOK = (access(xmlPath.c_str(), F_OK) == 0); #endif diff --git a/src/SMESHUtils/SMESH_File.cxx b/src/SMESHUtils/SMESH_File.cxx index 86723df99..1e249c430 100644 --- a/src/SMESHUtils/SMESH_File.cxx +++ b/src/SMESHUtils/SMESH_File.cxx @@ -81,12 +81,12 @@ bool SMESH_File::open() if ( !_map && length > 0 ) { #ifdef WIN32 -#ifdef UNICODE +# ifdef UNICODE std::wstring aName = Kernel_Utils::utf8_decode_s(_name); const wchar_t* name = aName.c_str(); -#else +# else char* name = _name.data(); -#endif +# endif _file = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); bool ok = ( _file != INVALID_HANDLE_VALUE ); diff --git a/src/SMESHUtils/SMESH_TypeDefs.hxx b/src/SMESHUtils/SMESH_TypeDefs.hxx index f6fcdb505..a682b894d 100644 --- a/src/SMESHUtils/SMESH_TypeDefs.hxx +++ b/src/SMESHUtils/SMESH_TypeDefs.hxx @@ -104,6 +104,8 @@ namespace SMESHUtils TOBJ* _obj; ArrayDeleter( TOBJ* obj ): _obj( obj ) {} ~ArrayDeleter() { delete [] _obj; _obj = 0; } + operator TOBJ*() { return _obj; } + TOBJ* get() { return _obj; } private: ArrayDeleter( const ArrayDeleter& ); }; diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index f997c096c..363e8d7aa 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -460,18 +460,17 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp // load plugin library if(MYDEBUG) MESSAGE("Loading server meshers plugin library ..."); #ifdef WIN32 -#ifdef UNICODE +# ifdef UNICODE const wchar_t* path = Kernel_Utils::decode_s(aPlatformLibName); -#else + SMESHUtils::ArrayDeleter deleter( path ); +# else const char* path = aPlatformLibName.c_str(); -#endif +# endif #else const char* path = aPlatformLibName.c_str(); #endif LibHandle libHandle = LoadLib( path ); -#if defined(WIN32) && defined(UNICODE) - delete path; -#endif + if (!libHandle) { // report any error, if occurred @@ -5194,7 +5193,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, TCollection_AsciiString aStudyName( "" ); if ( isMultiFile ) { CORBA::WString_var url = aStudy->URL(); - aStudyName = (char*)SALOMEDS_Tool::GetNameFromPath( Kernel_Utils::encode(url.in()) ).c_str(); + SMESHUtils::ArrayDeleter urlMulibyte( Kernel_Utils::encode( url.in()) ); + aStudyName = (char*)SALOMEDS_Tool::GetNameFromPath( urlMulibyte.get() ).c_str(); } // Set names of temporary files TCollection_AsciiString filename = tmpDir + aStudyName + "_SMESH.hdf"; -- 2.39.2