0

Я написал этот код, чтобы показать строковые шейп-файлы в окне opengl.
Фактически это код Rendering Shapefile in OpenGL here in code-project, но я делаю некоторые изменения на нем, чтобы читать фигуры с библиотекой OGR, а не 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 

, когда я комментирую строку:

delete poPointTemp; 

нет никакой ошибки, и форма рисуется на окне OpenGL правильно. Но, как вы знаете, это утечка памяти, поэтому, когда мне не нужен poPointTemp, я должен удалить ее.
Но на линии:

delete poPointTemp; 

Я получаю сообщение об ошибке во время выполнения:

enter image description here

Я отлажена мой код и адрес и содержимое poPointTemp перед запуском этой линии заключается в следующем :

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

poPointTemp Я имею в виду не является указателем NULL, а также адрес, в котором у нас нет доступа, не совпадает с адресом poPointTemp !!!

Как вы думаете, в чем проблема моего кода?

Я попытался свести к минимуму код настолько, насколько могу. Поэтому, если вы хотите отлаживать код самостоятельно, вы можете скачать его в code-project, а затем просто внесите в него изменения в соответствии с кодом, который я написал выше.

  • , пожалуйста, используйте мой OpenShapeFile метод вместо соответствующего метода Кодекса и сделать другие изменения в код.
    Также я загрузил свой код here in 4shared, вы можете взять его здесь и просто соединить GDAL Library и запустить его.

Конечно, с помощью Джона ответить моя проблема была исправлена. Но я по-прежнему буду ценить кого-то, кто скажет мне, в чем проблема вышеуказанного кода?

+0

Вы минимизируется этот код? – Beta

+0

@Beta Что вы подразумеваете под минимизацией? – sepideh

+0

Я имею в виду сокращение его до [минимального полного примера] (http://sscce.org/). Упростите код как можно больше, сохраняя при этом ошибку. (И если это вообще возможно, дайте нам все, что нужно, чтобы воспроизвести ошибку.) Это помогает довольно много. – Beta

ответ

1

Это не совсем ответ, но он может помочь, и слишком поздно добавить комментарий. Также имейте в виду, что я не знаю эту библиотеку, поэтому мой совет может быть неправильным.

Несомненно, эта ошибка маскирует реальную ошибку, которая находится где-то еще в вашем коде. Как вы говорите, должен удалить память в этот момент. Однако мне кажется, что вы ненужно выделяете память.Например, это

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; 

можно переписать без выделения памяти, как этот

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

Подобное изменение может быть сделано для poPointTemp. В общем случае, если вы обнаружите, что выделяете память для объекта, а затем удаляете его в той же области, это указывает на то, что вам вообще не нужно выделять память.

Ничего из этого не устранит ошибку, которая по-прежнему скрыта, но дело в том, что, упрощая код и выделяя меньше памяти, вы приблизитесь к реальной ошибке, что, несомненно, является своего рода повреждением памяти.

+0

ОК @john, но я пробовал то, что вы сказали раньше. в коде, который вы предложили, будет встречена ошибка 'poEnvelope используется без инициализации' и' poPointTemp используется без инициализации' в следующей строке. и если я попытаюсь инициализировать их с помощью «NULL», я получу еще одну ошибку, потому что я думаю, что их структура меняется. – sepideh

+0

OK @john, вы правы. На самом деле я искал способ избавиться от ненужного выделения памяти. На самом деле я немного новичок в C++, и иногда я забываю, что '& x' является указателем на' x'. – sepideh

0

У меня была та же проблема. Ваш код верен.

В моем случае проблема была другая gdal.dll в PATH. Убедитесь, что исполняемый файл загружает нужную библиотеку.

(Там очень много от приложения, которое поставляется с gdal.dll, и добавить их папку в PATH. Как QGIS или GeoConCept ...)