How to correctly read geometries from a shapefile using gdal and ogr and freeing the geometries without memory leaks?
Here is a minimal example that continously reads and tries to free the geometries, but memory is never released and is consumed more and more. Example is made with Qt.
#include <QCoreApplication>
#include <QTextStream>
#include <QDebug>
#include <gdal/gdalwarper.h>
#include <gdal/ogrsf_frmts.h>
void freeshapes1(QList<OGRGeometry*> vectors){
foreach (OGRGeometry* vector, vectors) {
delete vector;//Leaks
//OGRGeometryFactory::destroyGeometry(vector);//Leaks
}
}
QList<OGRGeometry*> loadshapes1(QString vecfile){
QList<OGRGeometry*> retval;
unsigned int openFlags = GDAL_OF_VECTOR | GDAL_OF_READONLY;
GDALDataset * srcDataset = static_cast<GDALDataset *>( GDALOpenEx(
(const char*)vecfile.toLocal8Bit().data(),
openFlags,
NULL, NULL, NULL ) );
OGRLayer *layer = srcDataset->GetLayer(0);
OGRFeature *feature;
layer->ResetReading();
while ((feature = layer->GetNextFeature()) != nullptr) {
OGRGeometry *geometry = feature->GetGeometryRef();//Leaks
//OGRGeometry *geometry = feature->StealGeometry();//Leaks
if(geometry == nullptr){
continue;
}
retval.append(geometry);
}
GDALClose(srcDataset);
return retval;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qWarning() << "Enter to start application";
QTextStream input(stdin);
input.readLine();
GDALAllRegister();
for(int i = 0; i < 1000; i++){
if( i % 100 == 0){
qWarning() << i;
}
QList<OGRGeometry*> list = loadshapes1(MY_VECTOR_PATH);
freeshapes1(list);
}
qWarning() << "Application done, check memory";
input.readLine();
return 0;
}
From the GDAL documentation: https://gdal.org/doxygen/classOGRLayer.html#a47d21ff33b32d14fa4e9885b9edecad6
OGRFeature * OGRLayer::GetNextFeature ( )
pure virtual
Fetch the next available feature from this layer.
The returned feature becomes the responsibility of the caller to delete with OGRFeature::DestroyFeature()
. It is critical that all features associated with an OGRLayer
(more specifically an OGRFeatureDefn
) be deleted before that layer/datasource is deleted.
OGRFeature::GetGeometryRef
returns a pointer to an internal field in the feature object. You should free the feature object.