Russian Qt Forum
Ноябрь 24, 2024, 12:31 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: ошибки при динамическом создании виджета  (Прочитано 6992 раз)
alezhe
Гость
« : Февраль 18, 2012, 23:16 »

доброго времени суток

пытаюсь динамически создать виджет из слота

Код:
void segregation::make_order(int n, double cr){
    int i,j;
//динамически создаю массивы
    QString *ar1=new QString[n];
    double  *ar2=new double[n*n];
//заполняю их значениями из данного экзэмпляра
    for (i=0; i<n; ++i){
        ar1[i]=ar_source1[i];
        for (j=0; j<n; ++j){
            ar2[i*n+j]=ar_source2[i*n+j];
        }
    }
//пытаюсь использовать указатели для создания дочернего
//экзэмпляра другого класса
    (new ordering(this, n, ar1, ar2, cr))->show();
}

результат непредсказуемый и недескретный
при одинаковом наборе действий происходят разные события:
код может выполниться успешно
или дизайнер может выдать ошибку SIGSEGV в произвольном месте, например в конструкторе создаваемого виджета на вроде бы безобидной команде типа "dist_in=new double[n*n];" или на какой-нибудь инструкции процессора или библиотечном классе

может кто-нибудь посоветовать на что следует обратить внимание
спасибо
 
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Февраль 19, 2012, 01:50 »

скорее всего неудаление динамических массивов ar1 и ar2 приводит к порче памяти.

а почему бы не использовать QList/QVector/QStringList (ну или STL-аналоги)?
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
alezhe
Гость
« Ответ #2 : Февраль 19, 2012, 02:23 »

Цитировать
скорее всего неудаление динамических массивов ar1 и ar2 приводит к порче памяти.

ну, вообще идея в том, что бы экземпляр класса ordering и оперировал данными из созданных динамических массивов ar1 и ar2
это названия и матрица расстояний, соответственно
в виду этого также, и не использую контейнеры, так как далее алгоритмически удобнее пользоваться таким массивом

не думаю, что копирование элементов непосредственно в конструкторе ordering и последующее высвобождение памяти позволит решить проблему (разве что непосредственно из ar_source1 и ar_source2) так как остановка выполнения программы иногда происходит прямо в конструкторе ordering

я ведь правильно пониманию, ни завершение функции make_order, ни удаление этого экземпляра segregation (он не последний чайлд QAplication) не должно повлиять на доступность к динамическим массивам ar1 и ar2?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #3 : Февраль 19, 2012, 02:54 »

не думаю, что копирование элементов непосредственно в конструкторе ordering и последующее высвобождение памяти позволит решить проблему (разве что непосредственно из ar_source1 и ar_source2) так как остановка выполнения программы иногда происходит прямо в конструкторе ordering
а, так эти динамические массивы просто присваиваются (без выделения памяти) каким-то другим в конструкторе ordering, и когда-то потом в ordering (например в деструкторе) удаляются? это, вообще говоря, очень неинтуитивное поведение.
я ведь правильно пониманию, ни завершение функции make_order, ни удаление этого экземпляра segregation (он не последний чайлд QAplication) не должно повлиять на доступность к динамическим массивам ar1 и ar2?
по идее да
Цитировать
(new ordering(this, n, ar1, ar2, cr))->show();
эта запись тоже далеко не из лучших, хотя вроде как проблем не должна создавать. попробуй создавать и показывать виджет через переменную - вдруг поможет.

ну и ещё вариант - память портится где-то раньше Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
alezhe
Гость
« Ответ #4 : Февраль 19, 2012, 03:15 »

Цитировать
память портится где-то раньше
вот я и думаю, где же я мог так напортить  Непонимающий
что аж новый объект создается лишь в 1/3 случаев  Обеспокоенный

и ordering я пробовал создавать с указателями (как с членами класс segregation, так и объявленным внутри метода, приведенный вариант - упрощенный)

может компилятор сменить?

все работает нормально, если создавать ordering в конструкторе segregation, но при этом нужно пересылать полный набор данных, а основная идея, как раз в их выборочности

Цитировать
попробуй создавать и показывать виджет через переменную
и еще про переменные-указатели:
ошибка также иногда возникала на стадии
p_ordering->show();
« Последнее редактирование: Февраль 19, 2012, 03:28 от alezhe » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #5 : Февраль 19, 2012, 03:42 »

вряд ли дело в компиляторе Подмигивающий

покажи конструктор ordering
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
alexandros
Гость
« Ответ #6 : Февраль 19, 2012, 12:35 »

Попробуй QStringList
Записан
alezhe
Гость
« Ответ #7 : Февраль 19, 2012, 13:25 »

конструктор ordering
он немного отличается по параметрам от приведенного в первом сообщении,
в первом сообщении я немного изменил прототип, для простоты восприятия

Код:
ordering::ordering(QWidget *parent, int i_n, QString *i_genes, double i_crit,
                   double *i_dist_in, double *i_recomb_in) :
    QWidget(parent,Qt::Window)
{
    //присваиваю членам класс входящие значения
    n=n_e=i_n;
    m_crit=crit=i_crit;
    genes=i_genes;
    dist_in=i_dist_in;
    recomb_in=i_recomb_in;
    //создаю новые массивы для промежуточных и итоговых расчетов
    exist=new bool[n];
        for (int i=0; i<n; ++i){exist[i]=true;};
    tree=new bool[n*n];
    conn_in=new bool[n*n];
    ways_in=new double[n*n];
    center=new double[n];
    genes_sr=new QString[n];
    dist_sr=new double[n*n];
    recomb_sr=new double;
    conn_sr=new bool[n*n];
    ways_sr=new double[n*n];
    dist_md=new double[n*n];
    msp_sr=new double[n*n];
    coord=new double[n*n];
    //методы класса осуществляют расчеты
    definecenter();
    cent_ch(-1);
    //создание элементов для компоновки и отображения элементов
    panel_layout=new QHBoxLayout(this);
    right_layout=new QVBoxLayout(this);
    table_layout=new QVBoxLayout(this);
    p_box=new points_box(this,n,genes);
    r_box=new relation_box(this, m_crit);
    graph=new d2_graf(this, n, &n_e, genes_sr, coord, conn_sr, tree);
    //компоновка элементов
    setLayout(panel_layout);
    panel_layout->addWidget(p_box);
    panel_layout->addLayout(right_layout);
    panel_layout->addLayout(table_layout);
    right_layout->addWidget(r_box);
    right_layout->addWidget(graph);
    //
    connect(p_box, SIGNAL(point_selection(int)), this, SLOT(cent_ch(int)));
    connect(p_box, SIGNAL(point_enabling(bool*)), this, SLOT(poin_ch(bool*)));
    connect(this, SIGNAL(point_en_back(bool*)), p_box, SLOT(points_depend(bool*)));

    //отображение промежуточных результатов
    //здесь table получает значение члена класса ordering (адрес массива)
    //его размеры и отображает содержимое
    t0=new table(this, n, n, dist_sr);
    table_layout->addWidget(t0);
    t1=new table(this, n, n, ways_sr);
    table_layout->addWidget(t1);
    t3=new table(this, n, n, conn_sr);
    table_layout->addWidget(t3);
    t2=new table(this, n, n, coord);
    table_layout->addWidget(t2);
    t5=new table(this, 1, n, center);
    table_layout->addWidget(t5);
    t6=new table(this, n, n, tree);
    table_layout->addWidget(t6);
}
« Последнее редактирование: Февраль 19, 2012, 13:46 от alezhe » Записан
alezhe
Гость
« Ответ #8 : Февраль 19, 2012, 13:47 »

Попробуй QStringList

QStringList - для передачи массива QString-ов??
не помогло
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #9 : Февраль 19, 2012, 14:57 »

больше одного лэйаута не может принадлежать одному и тому же виджету (но вряд ли падает из-за этого), так что
Код
C++ (Qt)
   right_layout=new QVBoxLayout(this);
   table_layout=new QVBoxLayout(this);
замени на
Код
C++ (Qt)
   right_layout=new QVBoxLayout;
   table_layout=new QVBoxLayout;
и строчка setLayout(panel_layout) не нужна, т.к. ты panel_layout'у уже задал родителя (это не ошибка, а просто лишняя команда).

конструктор вроде выглядит нормально. можешь выложить весь проект?
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
alezhe
Гость
« Ответ #10 : Февраль 19, 2012, 15:32 »

больше одного лэйаута не может принадлежать одному и тому же виджету

спасибо, я это всегда подозревал, так как одно время были проблемы с памятью при уничтожении объектов, сделанных таким образом ))
теперь буду делать правильно

прикладываю файл с проектом
там же небольшое пояснение в файле description.txt
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #11 : Февраль 19, 2012, 17:15 »

а ты каким компилятором собираешь? студийный компилятор не разрешает выражение вида 0.0/0 и pow(int,int) (первое решается через std::numeric_limits<double>::quiet_NaN(), второе - через static_cast). есть ещё предупреждение о двух "одинаковых" конструкторах table - конструкторы не могут отличаться только типом параметра, у которого есть значение по умолчанию.

в окно вывода заглядываешь? у тебя вышеописанная ошибка с лэйатуами много где присутствует.

кириллица в исходниках и кодировка windows-1251 - это не очень хорошо.

судя по всему падает в table::paintEvent() при отрисовке текста. вполне возможно как раз из-за того, что используется неправильный конструктор по умолчанию.

убрал значения по умолчанию, закомментировал close_this() в _grouping.cpp:221 - всё заработало, только диалог поверх остаётся. если раскомментировать - падает.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
alezhe
Гость
« Ответ #12 : Февраль 19, 2012, 20:37 »

kambala, спасибо за помощь

пользуюсь QT Creator 2.3.1

из сообщений сборки у меня:
то что не все возможные варианты множества enum задействованы в switch
деление на ноль
и ошибки касающиеся используемой библиотеки alglib
про table никаких предупреждений не выдает

убрал для table значения по умолчанию, конструктор с булевым массивом, а затем и само использование table
а также исключил функцию, которая прятала диалоговое окно close_this() в grouping

(субъективно) частота успешного создания ordering возросла, но все равно программа падает

какие-то у меня принципиальные непонимания принципов Qt  Грустный

проблема не решена

может быть это связано с использованием сигналов? имеет смысл напрямую вызывать функцию?

и для своего развития, чем плоха кодировка windows-1251 ?
Записан
Bepec
Гость
« Ответ #13 : Февраль 20, 2012, 06:55 »

Добрый человек, а Qt у тебя версии какой?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #14 : Февраль 20, 2012, 13:02 »

то что не все возможные варианты множества enum задействованы в switch
вообще-то там говорится о том, что не все control paths (не знаю как это по-русски правильно называется) возвращают значение - достаточно просто последний возврат делать не из else
убрал для table значения по умолчанию, конструктор с булевым массивом, а затем и само использование table
а также исключил функцию, которая прятала диалоговое окно close_this() в grouping

(субъективно) частота успешного создания ordering возросла, но все равно программа падает
странно, у меня всё стало работать как только я убрал скрытие диалога...
может быть это связано с использованием сигналов? имеет смысл напрямую вызывать функцию?
тоже может быть, попробуй
и для своего развития, чем плоха кодировка windows-1251 ?
плохая переносимость между системами. то ли дело UTF-8!

добавлено: кажется я понял в чём тут дело. при критическом значении  0.1 и ниже падает всегда, при больших значениях - всё стало ок. применённые фиксы:
  • убран деструктор grouping и создание элементов карты производится с родителем source
  • в segregation убрал модальность у диалога группировки с помощью group_dialog->setModal(false)
но всё равно часто падает при выходе из программы или при повторной попытке группировки
« Последнее редактирование: Февраль 20, 2012, 13:39 от kambala » Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.096 секунд. Запросов: 23.