crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> QWT, QwtPlotCurve::setData(), bad_alloc
Алексей1153
  опции профиля:
сообщение 14.5.2013, 8:33
Сообщение #1


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


версия QWT 5.2.1

столкнулся с такой вещью - если в QwtPlotCurve::setData() передаю большой массив, а там, внутри, невозможно выделить память под этот массив (поскольку там происходит копирование, да потом ещё и для самой отрисовки наверняка память выделяется), оттуда выпадает исключение std::bad_alloc. Тут пока всё понятно, и это перехватить я могу. Но прикол ещё в том, что можно оказаться где-то на грани, когда из QwtPlotCurve::setData() исключение ещё не вылетит, а при первой же попытке отрисоваться объект QwtPlotCurve кидает исключение. Тут опять - я могу перехватить его в QwtPlotCurve::draw() или QwtPlotCurve::drawCurve() - это тоже удаётся, но потом, дальше, где-то падает. Я по стеку глянул, куда идём после QwtPlotCurve::drawCurve() , добрался до paintEvent канваса. Поскольку сам канвас переназначить метода нет, я поставил фильтр на его сообщения в плоттере

this->canvas()->installEventFilter(this);

но ловля тут не удаётся никаким боком - падает где- то, зараза

bool ...::eventFilter(QObject *o, QEvent *e)
{
    if(o==this->canvas())
    {
        try
        {
            return QwtPlot::eventFilter(o,e);
        }
        catch(std::exception& e)
        {
            qDebug()<<e.what();
            return true;
        }
        catch(...)
        {
            qDebug()<<"catch(...)";//тут тоже ничего не ловится
            return true;
        }
    }

    return QwtPlot::eventFilter(o,e);
}


а вот так я имитирую "большие" данные

QwtPlotCurve* curve=new QwtPlotCurve();

try
{
   //big data
   uint32_t N=0x02000000;
   std::vector<double> x(N,0);// 512 метров в итоге (N*2*sizeof(double)),
   std::vector<double> y(N,0);//  и ещё столько же будет выделено в setData()

   //если исключение кинулось уже тут, в векторе, то всё зашибись.
   //по докам - вектор гарантированно не меняется, если не удалось выделить память


   curve->setData(x,y,N);//отсюда исключение ловится - см. catch

   curve->attach(this);

   curve->show();//...//а отсюда не очень. Вернее, тут портится curve, а позже падает
}
catch(std::exception& e)
{
   curve->detach();//отцепляю от плоттера
   //delete curve  //удалять нельзя - упадёт в деструкторе
   curve=0;//а так - хотя бы просто небольшая утечка памяти, но без последствий
}


значение 0x02000000 подобрано методом научного тыка - где-то на этой грани (плюс-минус байты) начинается лажа

--------------------------
как это побороть, кроме как написать свой класс отображения графиков ? :)

а, да, разрабам написал на почту отсюда http://qwt.sourceforge.net/ , но пока тишина.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 14.5.2013, 9:20
Сообщение #2


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Переопределять eventFilter бесполезно, потому что он фильтрует события а не вызывает обработчики.
Можно переопределить метод event(или чего уж там, paintEvent) и там отлавливать.

Но что то мне подсказывает, что если вылезает bad_alloc, то данных слишком много, может подумать над их подкачкой?
Кстати в 6 версии используется
http://qwt.sourceforge.net/class_qwt_series_data.html

С ним можно абстрагироваться от непрерывного массива и сделать "окно" в принципе любого размера.
(в 5 версии называется QwtData и тоже в принципе похож)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 14.5.2013, 9:29
Сообщение #3


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


lanz, тут смотри, какая ведь штука. Валится в paintEvent канваса, а

Цитата(Алексей1153 @ 14.5.2013, 11:33) *
сам канвас переназначить метода нет,


поэтому я могу произвести класс от QwtPlotCanvas , но назначить этот объект в плоттер не могу. И это всё отпадает

Попробую обновить версию тогда
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 14.5.2013, 10:00
Сообщение #4


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


насколько я понял, QwtData - это интерфейс, а саму подкачку надо делать в нём вручную ? Например при помощи маппинга файлов ? или там есть уже что-то готовое
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 14.5.2013, 10:05
Сообщение #5


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Цитата
или там есть уже что-то готовое

Не видел, по моему нету. Но я специально не искал :lol:

Цитата
lanz, тут смотри, какая ведь штука.

Думал по paintEvent QwtPlot, но он не переопределен, так что либо его event, либо одно из двух :lol:

Насчет обновления версии, я посмотрел в пятой версии тоже есть QwtData, может ее будет достаточно.

EDIT: Что то мне мысли по очереди приходят :lol:
В 6 версии есть клевый метод setRectOfInterest, который может пригодится.
http://qwt.sourceforge.net/class_qwt_serie...582fbc2662d108e

Сообщение отредактировал lanz - 14.5.2013, 10:17
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 14.5.2013, 10:16
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


да, QwtData я тут нашёл тоже

оборачивание QwtPlot::event тоже результата не даёт, ну это я так и предполагал
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 14.5.2013, 11:53
Сообщение #7


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Цитата
оборачивание QwtPlot::event тоже результата не даёт, ну это я так и предполагал


Да, я поковырял исходники, видимо paintEvent доходит до canvas через родителя по родным Qt-шным трубам (через спонтанные paint events? Призываются знатоки :lol:)
Т.е. можно попробовать обернуть
Раскрывающийся текст
app.exec ()

EDIT: попробовал, но тоже не ловит, что странно.

Сообщение отредактировал lanz - 14.5.2013, 12:10
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 14.5.2013, 12:39
Сообщение #8


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


lanz, шаманцтво!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 24.4.2024, 12:51