На главную... Продукты | Технологии | Классификаторы | Проекты | Скачать | Цены| Форум | Статьи | Обучение | Контакты

Подозрение на утечку памяти в QDMapView

Поиск  Пользователи  Правила  Войти
Форум » Linux » Средства разработки ГИС-приложений для Linux
Страницы: 1
RSS
Подозрение на утечку памяти в QDMapView, Valgrind выдаёт утечку памяти в конструкторе QDMapView
 
Здравствуйте!

ГИС Конструктор для Linux, установлен на Ubuntu 16.

При запуске приложения с включенным анализатором памяти Valgrind при выходе из приложения зафиксирована утечка памяти, стек вызова прилагаю.

4,472 (72 direct, 4,400 indirect) bytes in 1 blocks are definitely lost in loss record 10,684 of 10,731
 в NvsMap::NvsMap(QObject*) in /home/user/nvsmap/src/map/nvsmap.cpp:22
 1: operator new(unsigned long) in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
 2: QDMapSelect::QDMapSelect(QDMapViewAcces*) in /usr/lib/libmapcomponents.so
 3: QDMapView::QDMapView(QWidget*, char const*) in /usr/lib/libmapcomponents.so
 4: NvsMap::NvsMap(QObject*) in /home/user/nvsmap/src/map/nvsmap.cpp:22
 5: main in /home/user/nvsmap/src/main.cpp:91

в хедере следующая инфрмация о версии

/******** QDMCMP.H ************** Dishlenko S.G.  ****** 02/06/06 **
******** QDMCMP.H ************** Savelov A.S.    ****** 21/01/16 **

Прошу проверить факт утечки памяти
 
Там есть утечки, я находил, можете вручную пройтись поиском по всем компонентам (по ключевому слову new) и исправить.

Файлик с тем что я находил ( в самом конце как раз QDMapSelect)
Код
int  QDMapPointAcces::ConvertMetric(double *x, double *y, int placein, int placeout)
{
  double OldPlaceIn, OldPlaceOut;
  double VarXold, VarYold;
  int    ret = 0;

  if (VarMapView->GetMapHandle() == 0) return ret;
  VarXold      = VarX;
  VarYold      = VarY;
  OldPlaceIn   = VarPlaceIn;
  OldPlaceOut  = VarPlaceOut;
  SetPlaceIn(placein);
  SetPlaceOut(placeout);

  SetPoint(*x, *y);
  GetPoint(x, y);

  VarX      = VarXold;
  VarY      = VarYold;
  VarPlaceIn  = OldPlaceIn;
  VarPlaceOut = OldPlaceOut;
}



char *QDMapSemantics::GetSemanticNameCode(int code)
{
  RSCSEMANTICEX tmp1;
  char          *ret = Value;

  memset(Value, 0, sizeof(Value));                                           // 18/10/05
  if (mapGetRscSemanticExByCode(GetRscHandle(), &tmp1, code) == 0) return ret;

  strcpy(Value, tmp1.Name);
  return tmp1.Name;
}


//------------------------------------------------------------------
//   Конструктор
//------------------------------------------------------------------
QDMapLayers::QDMapLayers(QDMapViewAcces *mapview, QDMapSite *mapsite)
{
    VarMapLayer = new QDMapLayer(mapview, mapsite);
}

//------------------------------------------------------------------
//   Конструктор для работы с отдельно открытым RSC
//------------------------------------------------------------------
QDMapLayers::QDMapLayers(HRSC rsc)
{
    QDMapLayers(NULL, NULL);
    SetRscHandle(rsc);
}



int QDMapViewWindow::SetViewScale(int value)
{
  long int x, y;
  int      oldscale;
  bool     VarRend = VarRendering;
  POINT    point1;
  RECT     rect;
  long int mapW, mapH;

  if (!GetMapHandle())
    return 0;

  oldscale = mapGetShowScale(GetMapHandle());
  if (oldscale == value)
    return value;

  // Проверить условие, что ничего не рисуется в данный момент
  if(IsPainting == 0)
  {
    VarRendering = false;            // 07/05/15 Савелов
    // Установить флаг отрисовки
    IsPainting = 1;
    // Начинаем отрисовку - сделать скролл-бары неактивными,
    // чтобы не мешать
    HScrollBar->setEnabled(false);
    VScrollBar->setEnabled(false);

    if (VarMapVisible)
    {
      x = HScrollBar->value() + MapViewPort->width() / 2;
      y = VScrollBar->value() + MapViewPort->height() / 2;
    }
    else
    {
      x = VarHorzPos + MapViewPort->width() / 2;
      y = VarVertPos + MapViewPort->height() / 2;
    }

    mapSetViewScale(GetMapHandle(), &x, &y, value);

    VarHorzPos = x - MapViewPort->width() / 2;
    if (VarHorzPos < 0) VarHorzPos = 0;
    VarVertPos = y - MapViewPort->height() / 2;
    if (VarVertPos < 0) VarVertPos = 0;

    mapGetPictureSize(GetMapHandle(), &mapW, &mapH );

    VarPaintEnabled = 0;
    if (mapW - MapViewPort->width() > 0)
      HScrollBar->setMaximum(mapW - MapViewPort->width());
    else
      HScrollBar->setMaximum(0);
    if (VarHorzPos > HScrollBar->maximum())
    {
      HScrollBar->setValue(HScrollBar->maximum());
      VarHorzPos = HScrollBar->maximum();
    }
    else
      HScrollBar->setValue(VarHorzPos);

    if (mapH - MapViewPort->height() > 0)
      VScrollBar->setMaximum(mapH - MapViewPort->height());
    else
      VScrollBar->setMaximum(0);
    if (VarVertPos > VScrollBar->maximum())
    {
      VScrollBar->setValue(VScrollBar->maximum());
      VarVertPos = VScrollBar->maximum();
    }
    else
      VScrollBar->setValue(VarVertPos);

    qApp->processEvents();

    VarPaintEnabled = 1;

    point1.x = point1.y = 0;
    rect.left   = VarHorzPos;
    rect.top    = VarVertPos;
    rect.right  = VarHorzPos + MapViewPort->width();
    rect.bottom = VarVertPos + MapViewPort->height();

    mapDrawImageMap(hScreen, GetMapHandle(), &rect, &point1);

    VarRendering = VarRend;

    // 15/09/14 Железняков В.: восстановит флаг отрисовки
    IsPainting = 0;

    if (VarRendering) MapViewPort->update();
    return mapGetShowScale(GetMapHandle());
  }
}



// -----------------------------------------------------------------
// Функция изменения масштаба относительно текущей точки
//   Параметры: value - реальный масштаб, который желают получить
// -----------------------------------------------------------------
int QDMapViewWindow::SetViewScaleInPoint(int value)
{
  RECT  rClient;
  POINT MousePos;
  int   MOUSEMOVE = 1;     // Флаг перемещения мыши
  DOUBLEPOINT dis;         // Позиция мыши в районе в дискретах
  int      oldscale;
  bool     VarRend = VarRendering;
  POINT    point1;
  RECT     rect;
  long int mapW, mapH;

  if (!GetMapHandle())
    return 0;

  oldscale = mapGetShowScale(GetMapHandle());
  if (oldscale == value)
    return value;

  // Проверить условие, что ничего не рисуется в данный момент
  if(IsPainting == 0)
  {
    VarRendering = false;            // 07/05/15 Савелов
    // Установить флаг отрисовки
    IsPainting = 1;
    //----------------------------------------------
    // Позиция мыши на экране
    MessageHandler(0, MH_GETCURSORPOS, (long int)&MousePos, 0, 0);

    // Преобразование к координатам клиентной области
    MessageHandler(0, MH_SCREENTOCLIENT, (long int)&MousePos, 0, 0);

    // Клиентная область
    MessageHandler(0, MT_MAPWINPORT, MWP_GETCLIENTRECT, (long int)&rClient, 0);

    // Если мышь не в клиентной области - мышь не смещать
    if (MousePos.x < 0 || MousePos.x >= rClient.RT ||
        MousePos.y < 0 || MousePos.y >= rClient.DN)
    {
      MOUSEMOVE = 0;

      // Установить координаты мыши в середину клиентной области окна
      MousePos.x = (rClient.RT - rClient.LT)/2;
      MousePos.y = (rClient.DN - rClient.UP)/2;
    }

    // Преобразование к координатам района
    MousePos.X = HScrollBar->value() + MousePos.X;
    MousePos.Y = VScrollBar->value() + MousePos.Y;

    if (MOUSEMOVE)
    {
      dis.x = MousePos.x; dis.y = MousePos.y;
      mapPictureToMap(GetMapHandle(), &(dis.x), &(dis.y));
      mapMapToPlane(GetMapHandle(), &(dis.x), &(dis.y));
    }

    long int mousex = MousePos.x;
    long int mousey = MousePos.y;

    int move = mapSetViewScale(GetMapHandle(), &mousex, &mousey, value);

    MousePos.x = mousex;
    MousePos.y = mousey;


    if (move == 0)
    {
      // Восстановить флаг отрисовки
      IsPainting = 0;
      return 0;
    }

    VarHorzPos = MousePos.x - MapViewPort->width() / 2;
    if (VarHorzPos < 0) VarHorzPos = 0;
    VarVertPos = MousePos.y - MapViewPort->height() / 2;
    if (VarVertPos < 0) VarVertPos = 0;

    mapGetPictureSize(GetMapHandle(), &mapW, &mapH );

    VarPaintEnabled = 0;
    if (mapW - MapViewPort->width() > 0)
      HScrollBar->setMaximum(mapW - MapViewPort->width());
    else
      HScrollBar->setMaximum(0);

    if (VarHorzPos > HScrollBar->maximum())
    {
      HScrollBar->setValue(HScrollBar->maximum());
      VarHorzPos = HScrollBar->maximum();
    }
    else
      HScrollBar->setValue(VarHorzPos);

    if (mapH - MapViewPort->height() > 0)
      VScrollBar->setMaximum(mapH - MapViewPort->height());
    else
      VScrollBar->setMaximum(0);
    if (VarVertPos > VScrollBar->maximum())
    {
      VScrollBar->setValue(VScrollBar->maximum());
      VarVertPos = VScrollBar->maximum();
    }
    else
      VScrollBar->setValue(VarVertPos);

    qApp->processEvents();

    VarPaintEnabled = 1;

    point1.x = point1.y = 0;
    rect.left   = VarHorzPos;
    rect.top    = VarVertPos;
    rect.right  = VarHorzPos + MapViewPort->width();
    rect.bottom = VarVertPos + MapViewPort->height();

    mapDrawImageMap(hScreen, GetMapHandle(), &rect, &point1);

    VarRendering = VarRend;
    // 15/09/14 Железняков В.: восстановить флаг отрисовки
    IsPainting = 0;
    if (VarRendering) MapViewPort->update();

    if (MOUSEMOVE && VarMapVisible && VarRend)
    {
      mapPlaneToMap(GetMapHandle(), &(dis.x),&(dis.y));
      mapMapToPicture(GetMapHandle(), &dis.x, &dis.y);
      MousePos.x = dis.x;
      MousePos.y = dis.y;

      // Преобразование к координатам клиентной области
      MousePos.X = MousePos.X - HScrollBar->value();
      MousePos.Y = MousePos.Y - VScrollBar->value();

      // Клиентная область (меняется при удалении линеек скроллинга
      MessageHandler(0, MT_MAPWINPORT, MWP_GETCLIENTRECT, (long int)&rClient, 0);

      // Поместить мышь в клиентную область
      MousePos.x = max(16L,
                       min((long)MousePos.x,
                           (long)(rClient.RT-rClient.LT-16L)));
      MousePos.y = max(16L,
                       min((long)MousePos.y,
                           (long)(rClient.DN-rClient.UP-16L)));

      // Преобразование к координатам экрана
      MessageHandler(0, MH_CLIENTTOSCREEN, (long int)&MousePos, 0, 0);

      // Установить мышь
      MessageHandler(0, MH_SETCURSORPOS, (long int)&MousePos, 0, 0);
    }

    return mapGetShowScale(GetMapHandle());
  }
}




//------------------------------------------------------------------
// Для данного метода надо сначала восстановить масштаб
//------------------------------------------------------------------
void QDMapWindow::drawContents(QPainter* p, int cx, int cy, int cw, int ch)
{
    XIMAGEDESC tempImage;
    QImage tempQImage(cw, ch, QImage::Format_ARGB32 );
    POINT point;
    RECT rect;

    point.x    = 0;
    point.y    = 0;
    rect.left   = cx;
    rect.right  = cx + cw;
    rect.top    = cy;
    rect.bottom = cy + ch;

    tempImage.RowSize = tempQImage.bytesPerLine();
    tempImage.Width = tempQImage.width();
    tempImage.Height = tempQImage.height();
    tempImage.CellSize = tempImage.RowSize / tempImage.Width;
    tempImage.Depth = tempImage.CellSize * 8;

    tempImage.Point = (char*)tempQImage.bits();

    mapPaintToXImage(GetMapHandle(), &tempImage, point.x, point.y, &rect);
    p->drawImage(cx, cy, tempQImage);

    return;

 int  iScale;
 int  oldMapBright, oldMapContrast;
 HMAP oMap = 0;
 int  vtype;
 bool oldMapContour;

 oMap = GetMapHandle();
 oldMapBright   = 0;
 oldMapContrast = 0;
 iScale = 0;

 if (oMap != 0)
 {
   iScale = RestoreViewScaleWin();

    vtype = mapGetViewType(oMap);
    if ((vtype == 2) || (vtype == 4)) oldMapContour = TRUE;
    else oldMapContour = FALSE;
    if (oldMapContour != VarMapContour)
    {
      if (VarMapContour) mapSetViewType(oMap, 2);
      else mapSetViewType(oMap, 1);
    }
    oldMapBright = mapGetBright(oMap);
    if (oldMapBright != VarMapBright) mapSetBright(oMap, VarMapBright);
    oldMapContrast = mapGetContrast(oMap);
    if (oldMapContrast != VarMapContrast) mapSetContrast(oMap, VarMapContrast);

    SetViewSelectNow(VarViewSelect, false);
 }

 if (oMap != 0)
 {
   if (VarMapVisible)
   {
     if (VarRendering)
     {
       QRect rect;

       HScrollBar->setValue(VarHorzPos);
       VScrollBar->setValue(VarVertPos);

       rect.setLeft(cx);
       rect.setTop(cy);
       rect.setRight(cx + cw);  // 17/12/13
       rect.setBottom(cy + ch);

       RectDraw = rect;
       PaintOfMapAcces(p);
     }
   }
 }
// else
// {
//   XClearWindow(((XCONTEXT *)(PointerVarXDC))->xcDisplay,
//                ((XCONTEXT *)(PointerVarXDC))->xcWindow);
   VarPaintEnabled = 0;
// }

 if (oMap != 0)
 {
   SetViewSelectNow(VarMapView->VarViewSelect, false);

   RestoreViewScale(iScale);

   if (oldMapContour != VarMapContour)
   {
     if (oldMapContour) mapSetViewType(oMap, 2);
     else mapSetViewType(oMap, 1);
   }
   if (oldMapBright != VarMapBright) mapSetBright(oMap, oldMapBright);
   if (oldMapContrast != VarMapContrast) mapSetContrast(oMap, oldMapContrast);
 }
}





RECT QDMapWindow::GetRegionRect()
{
 int  iScale;
 RECT Result;

 iScale = 0;
 if (GetMapHandle() != 0) iScale = RestoreViewScaleWin();
 Result = QDMapViewWindow::GetRegionRect();
 RestoreViewScale(iScale);
}


//------------------------------------------------------------------
// определить габариты всего набора карт в указанной системе координат
//------------------------------------------------------------------
MAPDFRAME QDMapWindow::GetRegionDFrame(int pointplace)
{
 int       iScale;
 MAPDFRAME Result;

 iScale = 0;
 if (GetMapHandle() != 0) iScale = RestoreViewScaleWin();
 Result = QDMapViewWindow::GetRegionDFrame(pointplace);
 RestoreViewScale(iScale);
}


//========================================================
// Вызов формы для выбора объекта из классификатора
// Вход mv        - объект - карта
//      objinfo   -  начальные параметры диалога
//                   NumbSite = -1 - для выбора доступны все карты
//                            = >= 0 - доступна только конкретная карта
//                   Incode, либо Excode и Local, либо Name и Local - определяют
//                   с какого объекта начать выбор
//      locals    - перечень доступных типов локализаций объекта (должен
//                  указывать на массив, размерностью 6(количество локализаций))
// Выход - = 0 - выбор сделан и aObjInfo - заполненая структура
//         = 1 - отказ
//====================================================
bool SelectObjectFromRsc(QDMapView *mv, int *locals,
                         TMAPOBJECTINFO *objinfo)
{
  QDMapSelectObjectRsc *selobjdlg = NULL;
  bool               ret = false;

  if ((mv == NULL) || (mv->GetMapHandle() == 0)
      || (locals == 0))
     return ret;

  selobjdlg = new QDMapSelectObjectRsc(NULL);

  selobjdlg->SetMapView(mv);
  selobjdlg->FSiteNumber = objinfo->NumbSite;

  if (objinfo->Incode != 0)
    selobjdlg->FRetIncode = objinfo->Incode;
  else
    if (objinfo->ExCode != 0)
      selobjdlg->SetBeginObjectForExcode(objinfo->NumbSite,
                                    objinfo->ExCode, objinfo->Local);
    else
      if ((objinfo->Name != NULL) && (strlen(objinfo->Name) != 0))
        selobjdlg->SetBeginObjectForName(objinfo->NumbSite,
                                         objinfo->Name, objinfo->Local);
 for (int i = 0; i < 6; i++)
   selobjdlg->FLocals[i] = locals[i];
 ret = selobjdlg->Execute(objinfo);
 if (selobjdlg != NULL)
   delete selobjdlg;
}



//------------------------------------------------------------------
//  Установить  текущий объект карты в диалоге  по внешнему коду и локализации
//  Вход - sitenumber - номер карты в списке (для -1 - ищется во всех классификаторах)
//       - excode     - клас код объекта
//       - local      - локализация (для -1 - локализация любая)
//------------------------------------------------------------------
bool QDMapSelectObjectRsc::SetBeginObjectForExcode(int sitenumber,
                                            int excode, int local)
{
 HRSC       RscH;
 HMAP       MapH;
 HSITE      SiteH;
 int        SiteCount, iLocal, iSiteN;
 bool       Result = false;

 if (VarMapView == NULL) return Result;
 MapH = VarMapView->GetMapHandle();
 if (MapH == 0) return Result;

 if (sitenumber == -1)
 {
   iSiteN = 0;
   SiteCount = mapGetSiteCount(MapH);
 }
 else
 {
   iSiteN    = sitenumber;
   SiteCount = sitenumber;
 }

 while (iSiteN <= SiteCount)
 {
     SiteH = mapGetSiteIdent(MapH, iSiteN);
     if (SiteH == 0) break;
     RscH = mapGetRscIdent(MapH, SiteH);
     if (RscH = 0) break;
     if (local != -1)
       FRetIncode = mapGetRscObjectCodeByNumber(RscH, excode, local, 1);
     else // переберем все локализации
     {
       for (iLocal = 0; iLocal < 6; iLocal++)
       {
          FRetIncode = mapGetRscObjectCodeByNumber(RscH, excode, iLocal, 1);
          if (FRetIncode != 0) break;
       }
     }

     if (FRetIncode != 0)
     {
       FRetSite = iSiteN;
       Result   = true;
       break;
     }
     iSiteN++;
  }  // iSiteN <= SiteCount

  return Result;
}


//утечки памяти

QDMapView::QDMapView(QWidget *parent)
    :QDMapViewWindow(parent)
{
    VarMapFileName  = "";
    VarMapLayers    = new QDMapLayers(this, NULL);
    VarMapMtrs      = new QDMapMtrs(this);
    VarMapRsts      = new QDMapRsts(this);
    VarMapSites     = new QDMapSites(this);
    VarViewSelect   = new QDMapSelect(this);

    VarMapSemantics = new QDMapSemantics(this);
    SetClassName("QDMapView");

#ifdef BUILD_FREE                       // 29/09/15
    gisLink();
#endif
#ifdef BUILD_FREE_3D                    // 29/09/15
    gss3dLink();
#endif
}

//------------------------------------------------------------------
//   Деструктор
//------------------------------------------------------------------
QDMapView::~QDMapView()
{
    VarRendering = false;

    SetMapFileName("");
    delete VarMapLayers;
    delete VarMapMtrs;
    delete VarMapRsts;
    delete VarMapSites;
    delete VarMapSemantics;

    for (int i = 0; i < VarMapObjects.size(); i++)
    {
        ((QDMapComponent *)(VarMapObjects.at(i)))->Notification(this, OPREMOVE);
    }

    for (int i = 0; i < VarMapWindows.size(); i++)
    {
        ((QDMapWindow *)(VarMapWindows.at(i)))->Notification(this, OPREMOVE);
    }

    if (GetMapHandle() != 0)
    {
        mapCloseMap(GetMapHandle());
        VarMapHandle = 0;
    }
}

//Если использовать конструктор с HRSC, получим падение в деструкторе

//------------------------------------------------------------------
//   Конструктор
//------------------------------------------------------------------
QDMapLayers::QDMapLayers(QDMapViewAcces *mapview, QDMapSite *mapsite)
{
    VarMapLayer = new QDMapLayer(mapview, mapsite);
}

//------------------------------------------------------------------
//   Конструктор для работы с отдельно открытым RSC
//------------------------------------------------------------------
QDMapLayers::QDMapLayers(HRSC rsc)
{
    QDMapLayers(NULL, NULL);
    SetRscHandle(rsc);
}

QDMapLayers::~QDMapLayers()
{
    delete VarMapLayer;
}

//Так и должно быть ?

//------------------------------------------------------------------
//   Конструктор
//------------------------------------------------------------------
QDMapMetric::QDMapMetric(QDMapObjAcces *mapobj)
{
  VarMapObj   = mapobj;
  VarMapPoint = new QDMapPointAcces(VarMapObj->VarMapView);
}

//------------------------------------------------------------------
//   Деструктор
//------------------------------------------------------------------
QDMapMetric::~QDMapMetric()
{
}

//VarMapPoint не удаляется

//------------------------------------------------------------------
//   Конструктор
//------------------------------------------------------------------
QDMapSelect::QDMapSelect(QDMapViewAcces* mapview)
{
  CountSelect = 0;                                                // 16/03/10
  memset(VarListSelect, 0, sizeof(VarListSelect));
  memset(VarListUses, 0, sizeof(VarListUses));

  VarEdit    = false;
  VarMapView = NULL;
  memset((char *)&VarMapRect, 0, sizeof(VarMapRect));
  VarSite = 0;
  VarMapView =  0;
  VarMapPoint = 0;
  VarMapPoint = new QDMapPointAcces(0);                  // 22/11/03
  SetMapView(mapview);

  memset(StringOut, 0, sizeof(StringOut));     // 09/12/09
}

//------------------------------------------------------------------
//   Деструктор
//------------------------------------------------------------------
QDMapSelect::~QDMapSelect()
{
  int ii;

  for (ii = 0; ii < CountSelect; ii++)
    if (VarListSelect[ii] != 0)
    {
      mapDeleteSelectContext(VarListSelect[ii]);
      VarListSelect[ii] = 0;
    }

  CountSelect = 0;
  memset(VarListSelect, 0, sizeof(VarListSelect));
  memset(VarListUses, 0, sizeof(VarListUses));
  VarSite = 0;
}

Изменено: Владимир Егоров - 27.02.2018 11:22:07
 
Большое спасибо Владимир!

Этот файлик скорее стоит расценивать как bug report для разработчиков ГИС Конструктора...
 
А он у разработчиков есть, этот файлик ( с января кажется).
У них просто катастрофически маленькая команда по поддержке Linux.
Исправят в будущем (если уже не исправили, и у Вас немного устаревшая версия), как руки дойдут.

Мне кстати очень интересно пользуется ли кто-нибудь этими классами из libmapcomponents (QD*) ?
У меня есть подозрение, что все на чистом MAPAPI пишут.
Изменено: Владимир Егоров - 27.02.2018 18:30:31
 
Я - на MAPAPI, QD инициализирую только для разблокировки основной либы
 
Цитата
QD инициализирую только для разблокировки основной либы
Там вроде достаточно просто функцию вызывать, которая в конструкторе вызывается, GSSLink или как-то так.
 
В новой версии 12.3.0 под Астра Линукс утечки памяти в компонентах устранены
Страницы: 1
Читают тему (гостей: 1)



© КБ Панорама, 1991-2024

Регистрируясь или авторизуясь на форуме, Вы соглашаетесь с Политикой конфиденциальности