0

I have written this code in order to show line shapefiles in an opengl window.
In fact it's the code Rendering Shapefile in OpenGL here in code-project, but I'm making some changes on it in order to read the shapes with the OGR library not shapelib.

#include "ogrsf_frmts.h" 
//#include "shapelib\shapefil.h"

void OpenShapeFile(char* filename)
{
   int i = 0;
   int j = 0;
   OGRErr error;
   OGRDataSource *poDataSource;
   poDataSource = OGRSFDriverRegistrar::Open(filename,false);
   OGRLayer *poLayer;
   poLayer = poDataSource ->GetLayer(0);
   OGREnvelope *poEnvelope = new OGREnvelope();
   error = poLayer ->GetExtent(poEnvelope,true);
   sBoundingBox.fMaxX = poEnvelope ->MaxX;
   sBoundingBox.fMaxY = poEnvelope ->MaxY;
   sBoundingBox.fMinX = poEnvelope ->MinX;
   sBoundingBox.fMinY = poEnvelope ->MinY;
   delete poEnvelope;
   OGRwkbGeometryType GeometryType = poLayer ->GetGeomType();
   int NumberOfFeatures = poLayer ->GetFeatureCount(true);
   poLayer ->ResetReading();

   //Line Shapefile
   if ( wkbFlatten ( GeometryType ) == wkbLineString )
   {
       OGRFeature *poFeature;
       MyLineString2D lineString;

       //temporary pointer in order to store coordinates of individual line vertexes
       OGRPoint *poPointTemp = new OGRPoint();
       for ( i = 0; i < NumberOfFeatures; i++ )
       {
           poFeature = poLayer ->GetNextFeature();
           OGRGeometry *poGeometry;
           poGeometry = poFeature ->GetGeometryRef();
           if ( poGeometry != NULL )
           {
               OGRLineString *poLineString = (OGRLineString *)poGeometry;
               int NumberOfVertexes = poLineString ->getNumPoints();
               lineString.vPointList.resize(NumberOfVertexes);
               for ( j = 0; j < NumberOfVertexes ; j++ )
               {
                   poLineString ->getPoint(j,poPointTemp);
                   MyPoint2D ptTemp;
                   ptTemp.dX = poPointTemp ->getX();
                   ptTemp.dY = poPointTemp ->getY();
                   lineString.vPointList.at(j) = ptTemp;
               }
               vLines.push_back(lineString);
           }
           OGRFeature::DestroyFeature( poFeature );
       }
   delete poPointTemp;
   } 
}  

void initializeGL()
{
    //glClearColor (0.0, 0.0, 0.0, 0.0);
    glClearColor (1.0, 1.0, 1.0, 1.0);  

int main(int argc, char** argv)
{
//OpenShapeFile("Shapefiles\\poi.shp");//Point Shapefile
OpenShapeFile("Shapefiles\\strassen.shp");//Line Shapefile
//OpenShapeFile("Shapefiles\\gruenflaechen.shp");//Polygon Shapefile

when I comment the line:

delete poPointTemp;  

there's no error and the shape is drawn on an OpenGL window properly. But as you know it's kind of memory leaking so when I don't need poPointTemp I should delete it.
But at the line:

delete poPointTemp;  

I get the run-time error:

enter image description here

I have debugged my code and the address and contents of poPointTemp before running this line is as follows:

poPointTemp 0x00503a90 {x=3435936.3300000001 y=5790327.5999999996 z=0.00000000000000000 }  

I mean poPointTemp is not a NULL pointer and also the address of where we don't have access to is not the same as the poPointTemp's address!!!

what do you think is the problem of my code?

I have tried to minimize the code as much as I can. So if you want to debug the code yourself you can download it in code-project and then just make changes to it according to the code that I have written above.

  • please use my OpenShapeFile method instead of the code's corresponding method and do other changes to the code.
    Also I have uploaded my code here in 4shared, you can take it here and just link GDAL Library and run it.

Of course with the help of john's answer my problem got fixed. But I'll still appreciate someone who tells me what's the problem of the above code?

Sepideh Abadpour
  • 2,550
  • 10
  • 52
  • 88
  • Have you minimized this code? – Beta Sep 11 '13 at 06:42
  • @Beta what do you mean by minimizing? – Sepideh Abadpour Sep 11 '13 at 06:45
  • I mean reduced it to a [minimal complete example](http://sscce.org/). Simplify the code as much as you can, while still reproducing the bug. (And if at all possible, give us everything we need to reproduce the bug.) It helps quite a lot. – Beta Sep 11 '13 at 06:54
  • Are you sure it is the delete that is causing the problem and not something else being destroyed as it goes out of scope at the end of the block either right before or right after the delete? – Ade Miller Sep 11 '13 at 07:21
  • well @AdeMiller the error is produced at this line when I debug the code. – Sepideh Abadpour Sep 11 '13 at 07:25
  • well @Beta if you want to debug the code yourself you can just download the code in code-project I've included all the parts that I have made a change to that code so do these changes and debug the code. **I've altered the code in my question please see the above.**. In fact I'm not permitted to upload my codes in this site. But if you're desired to help me more I can upload it for you in 4shared. – Sepideh Abadpour Sep 11 '13 at 07:30
  • As @Beta suggests a minimal example would really help. You have several other pointers that will also cause memory leaks; poDataSource & poLayer are allocated and never freed. The error value is never checked. A call stack would really help narrow things down too, given the number of places that your code might be leaking. – Ade Miller Sep 11 '13 at 07:33
  • well @AdeMiller this code is not complete yet. of course after finishing work with `poDataSource` I will delete it using the `OGRDatasource::DestroyDataSource` function of the OGR library and since poLayer is taken from poDataSource it will be deleted that time using `OGRDatasource::DestroyDataSource`. this is what I have studied in ogr tutorials. – Sepideh Abadpour Sep 11 '13 at 08:02
  • I understand the code is incomplete but there are a number of things that might be causing this issue. So a) providing a minimal example to exclude other possibilities b) provide a call stack for your error which will also help narrow down the possibilities. As @john suggests below your crash may be masking another issue. – Ade Miller Sep 11 '13 at 20:15

2 Answers2

1

This is not really an answer but it might help and it's a bit too long to put in a comment. Also bear in mind that I don't know this library so my advice might not be correct.

Undoubtedly this error is masking the real error which is somewhere else in your code. As you say you should delete the memory at this point. However it does seem to me that you are unnecessarily allocating memory. For instance this

OGREnvelope *poEnvelope = new OGREnvelope();
error = poLayer ->GetExtent(poEnvelope,true);
sBoundingBox.fMaxX = poEnvelope ->MaxX;
sBoundingBox.fMaxY = poEnvelope ->MaxY;
sBoundingBox.fMinX = poEnvelope ->MinX;
sBoundingBox.fMinY = poEnvelope ->MinY;
delete poEnvelope;

could be rewritten without any memory allocation like this

OGREnvelope poEnvelope;
error = poLayer ->GetExtent(&poEnvelope,true);
sBoundingBox.fMaxX = poEnvelope.MaxX;
sBoundingBox.fMaxY = poEnvelope.MaxY;
sBoundingBox.fMinX = poEnvelope.MinX;
sBoundingBox.fMinY = poEnvelope.MinY;

A similar change could be made for poPointTemp. In general if you find yourself allocating memory for an object and then deleting it in the same scope it's an indication that you don't really need to allocate the memory at all.

None of this will fix the error which is still hidden, but the point is by simplifying your code and allocating less memory you will get closer to the real error, which is undoubtedly some kind of memory corruption.

john
  • 85,011
  • 4
  • 57
  • 81
  • ok @john but I have tried what you said before. the code that you have suggested will encounter the error `poEnvelope is being used without initialized` and `poPointTemp is used without being initialized` in the next line. and if I try to initialize them with `NULL` I will get another error because I think their structure is being changed. – Sepideh Abadpour Sep 11 '13 at 08:07
  • OK @john you're right. In fact I was searching for a way to get rid of these unnecessary memory allocation. In fact I'm a bit new in c++ and I forget sometimes that `&x` is a pointer to `x`. – Sepideh Abadpour Sep 11 '13 at 08:16
0

I had the same problem. Your code is correct.

In my case the problem was other gdal.dll in the PATH. Be sure that your executable load the right library.

(There's a lot off application that comes with gdal.dll, and add their folder to the PATH. Like QGis or GeoConcept...)

saad
  • 764
  • 4
  • 18