6

I am working on a project based on QGIS API c++ 2.8.2 and qt4.8.

I have two methods in a class, the first create a layer and add a point Here is the code for the creating:

LibCartoError CMyQgsS57::createPointLayer(QString pLayerName, QMap<QString,
        QVariant> pFeatureName)
{
    QgsVectorLayer * lVectorLayer = new QgsVectorLayer("Point?crs=epsg:4326", pLayerName, "memory");

    lVectorLayer->startEditing();
    QgsVectorDataProvider * lDataProvider = lVectorLayer->dataProvider();

    QMapIterator<QString, QVariant> lAttrib( pFeatureName );
    QList<QgsField> lMyAttribField;

    while (lAttrib.hasNext()) {
        lAttrib.next();
        // add attribute
        lMyAttribField << QgsField(lAttrib.key(), lAttrib.value().type());
    }
    lDataProvider->addAttributes( lMyAttribField );

    // save attributes
    lVectorLayer->commitChanges();

    // add to the map
    QgsMapLayerRegistry::instance()->addMapLayer( lVectorLayer );

    mMapLayer.insert(pLayerName, lVectorLayer);

    ((QList<QgsMapCanvasLayer>*)myListForPrint)->insert( 0, QgsMapCanvasLayer(lVectorLayer, TRUE) );
    // return 
    lError.error_code = NoError;
    lError.error_detail = "La creation de la couche Point " + pLayerName + " est effectuée";
    return lError;
}

I have a timer that delete this point if the result of an operation is good, else the point is kept in the map (or canvas).

Here is the code for deleting the layer:

LibCartoError CMyQgsS57::deleteLayer(QString pLayerName)
{
    LibCartoError lError;

    int lIndexOfLayer;
    bool lLayerFound = true;
    for (int k = 0; (k < ((QList<QgsMapCanvasLayer>*)myListForPrint)->size() && lLayerFound); k++)
    {
         if(((QList<QgsMapCanvasLayer>*)myListForPrint)->at(k).layer()->name() == pLayerName) {
            lIndexOfLayer = k;
            lLayerFound    = false;
        }
    }

    if( !lLayerFound )  {
        // delete the layer
        QgsVectorLayer* lLayertoDelete = NULL;
        lLayertoDelete = (QgsVectorLayer*) mMapLayer.value( pLayerName );

        QgsMapLayerRegistry::instance()->removeMapLayer( lLayertoDelete->id() );
        mMapLayer.remove( pLayerName );

        ((QList<QgsMapCanvasLayer>*)myListForPrint)->removeAt(lIndexOfLayer);
    }

    lError.error_code = NoError;
    lError.error_detail = "Layer :: " + pLayerName + " is deleted";
    return lError;
}

If I launch the system monitor, my application takes 4.4 MB each time the delete and create is invoked. If only the createpoint is invoked the use of memory is stable, but if I create / delete a lot of time I can see the use memory increasing.

Is there something missing in my code?

  • What OS are you using? – AnserGIS May 19 '16 at 14:16
  • i am working under ubuntu 14.04lts 32bits – ainardi May 19 '16 at 14:51
  • Have you tried the "removeMapLayers" function mentioned in this post? – kttii May 24 '16 at 18:40
  • in the code of qgis you can see that the removeMapLayer, used in my application, create a list and call finally removeMapLayers, it is useless to create a list of only one layer and call removeMapLayers – ainardi May 29 '16 at 6:35
2

In your createPointLayer you're creating a pointer on the heap and dynamic memory will be allocated. Then you remove only the references of this layer-object in map, registry and canvas. But I think you have to free the allocated memory with the delete command or better call the destructor of QgsVectorLayer::~QgsVectorLayer()

  • i have done a lot of tests, and also read the c++ class code of qgis at the adress qgis.org/api/2.8/classes.html. i remark that the memory allocated for my qgsvectorlayer* was really free with QgsMapLayerRegistry::->removeMapLayer().this method is called when i delete my QgsVectorLayer from the registry. it is useless to do it again. there is something strange about liberation of the memory allocation, if i call the refresh method of the qgsmapcanvas i can see in the Top event the amount of memory reduced, the same event when i do a map pan. is it my method to update point position ? – ainardi May 18 '16 at 13:24
  • Yes, I think after removing the layer you could call the refresh if you want to clear the memory immediatly. Probably QGIS 'keeps in mind' which layers have to be deleted/ memory allocated. Despite this you could give it a try to take ownership of the layer by calling QgsMapLayerRegistry::instance()->addMapLayer( lVectorLayer, true, true ); and delete it later by yourself, but I think its the same... – Ms. Smith May 19 '16 at 7:10
  • i have just made a new test, now i do addMapLayer(lVectorLayer,false,flase), by default the two parameters are true value, i have also manually delete the layer in memory. though these tests i have the same result and the same memory leak. if you have any idea i can make a lot of test. – ainardi May 19 '16 at 12:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.