[gdal-dev] help please with close/reopen and GDALSubdatasetInfo

Even Rouault even.rouault at spatialys.com
Sun Dec 3 05:11:29 PST 2023


Hi Michael,

It was most missing a "break;" statement when the subdataset of interest 
has been found to exit the loop. Without the break, the loop will 
continue to read papszSubdatasets[] which has been invalidated by the 
poSrcDS->ReleaseRef(). Ah, memory unsafe languages :-). You also had a 
few memory leaks.

Fixed version:

#include "gdal.h"
#include "gdal_priv.h"
#include <iostream>
int main(int argc, char **argv) {
   GDALAllRegister();

   auto poSrcDS =
     GDALDataset::Open(argv[1], GDAL_OF_RASTER, nullptr, nullptr, nullptr);
   if (poSrcDS == nullptr)
   {
     return 0;
   }
   char **papszSubdatasets = poSrcDS->GetMetadata("SUBDATASETS");
   int nSubdatasets = CSLCount(papszSubdatasets);
   if (nSubdatasets > 0)
   {
     for (int j = 0; j < nSubdatasets; j += 2)
     {
       char* pszSubdatasetSource = CPLStrdup(strstr(papszSubdatasets[j], 
"=") + 1);
       GDALSubdatasetInfoH info = 
GDALGetSubdatasetInfo(pszSubdatasetSource);
       char* component = info ? 
GDALSubdatasetInfoGetSubdatasetComponent(info) : NULL;
       const bool bFound = component && EQUAL(argv[2], component);
       CPLFree(component);
       GDALDestroySubdatasetInfo(info);
       if ( bFound) {
         std::cout << pszSubdatasetSource << "\n";
         poSrcDS->ReleaseRef();
         poSrcDS = GDALDataset::Open(pszSubdatasetSource, 
GDAL_OF_RASTER, nullptr, nullptr, nullptr);
         CPLFree(pszSubdatasetSource);
         break;
       }
       else {
         CPLFree(pszSubdatasetSource);
       }
     }
   }

   poSrcDS->ReleaseRef();
   return 1;
}

Even


Le 03/12/2023 à 05:10, Michael Sumner via gdal-dev a écrit :
> #include "gdal.h"
> #include "gdal_priv.h"
> #include <iostream>
> int main(int argc, char **argv) {
>   GDALAllRegister();
>
>   auto poSrcDS =
>     GDALDataset::Open(argv[1], GDAL_OF_RASTER, nullptr, nullptr, nullptr);
>   if (poSrcDS == nullptr)
>   {
>     return 0;
>   }
>   char **papszSubdatasets = poSrcDS->GetMetadata("SUBDATASETS");
>   int nSubdatasets = CSLCount(papszSubdatasets);
>   char *pszSubdatasetSource = nullptr;
>   if (nSubdatasets > 0)
>   {
>     for (int j = 0; j < nSubdatasets; j += 2)
>     {
>       pszSubdatasetSource = CPLStrdup(strstr(papszSubdatasets[j], "=") 
> + 1);
>       GDALSubdatasetInfoH info = 
> GDALGetSubdatasetInfo(pszSubdatasetSource);
>       if ( EQUAL(argv[2], 
> GDALSubdatasetInfoGetSubdatasetComponent(info))) {
>         std::cout << pszSubdatasetSource << "\n";
>         poSrcDS->ReleaseRef();
>         poSrcDS = GDALDataset::Open(pszSubdatasetSource, 
> GDAL_OF_RASTER, nullptr, nullptr, nullptr);
>         CPLFree(pszSubdatasetSource);
>         GDALDestroySubdatasetInfo(info);
>
>       }
>     }
>   }
>
>   poSrcDS->ReleaseRef();
>   return 1;
> }

-- 
http://www.spatialys.com
My software is free, but my time generally not.



More information about the gdal-dev mailing list