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.

_______________________________________________
gdal-dev mailing list
gdal-dev@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/gdal-dev

Reply via email to