11371
|
Программирование / С/C++ / Re: Почему не срабатывает блок try?
|
: Август 21, 2009, 12:42
|
Нет, конечно, твой вариант завершения я попробовал, все работает без нареканий. Но вопрос более общий, как перехватить ситуацию в коде вообще, когда происходит прерывание программы по какой то ошибке, например деление на ноль. Мне предложили _set_se_translator, но что то я не могу найти его применение в линуксе. Есть много в инете по виндовс. На своем диске с линуксом я прошелся поиском, тоже ничего нет. Только wine и bost. Существует ли общее решение проблемы?
Немного толку от перехвата общего "в программе произошла ошибка". Ну перехватили и что будете делать? Данные уже наверняка искалечены, остается показать окно с извинениями и выйти (да и то неизвестно живы ли еще окна). Имеет смысл перехватывать на каком-то участке, для этого есть try catch на любой платформе. Хотя перехват обращения по неверному адресу и возможен, это ошибка в программе которую надо исправлять, а не перехватывать
|
|
|
11372
|
Программирование / С/C++ / Re: Почему не срабатывает блок try?
|
: Август 21, 2009, 12:20
|
Вот код:
void Potok::ZapuskThread() { Pt=new PotokThread((QObject*)this); connect(Pt , SIGNAL(finished()), Pt , SLOT(deleteLater())); QObject::connect(Pt, SIGNAL(valueChanged(int)), ui.Zapolnenie, SLOT(setValue(int)), Qt::QueuedConnection); Pt->start(); };
Potok::~Potok() { delete Pt; };
Если происходит прерывание программы пока PotokThread не завершился, происходит утечка памяти, т.е. надо специально удалять объект. (Я так понимаю). Для этого надо проверить его валидность.
В С/C++ не существует способа проверить валидность указателя, надо полагаться на то что все операции с ним были корректны. В данном случае Вы перестарались и удаляете дважды Одно из удалений надо убрать Вариант 1 PotokThread * Pt=new PotokThread((QObject*)this); connect(Pt , SIGNAL(finished()), Pt , SLOT(deleteLater())); Не делайте Pt членом класса, если deleteLater его грохнет, Вы остаетесь с уже удаленным указателем Вариант 2 (по-моему лучше) // connect(Pt , SIGNAL(finished()), Pt , SLOT(deleteLater())); Т.е. просто уберите/отключите эту строку. Остальное как у Вас, только в деструктор неплохо бы добавить Potok::~Potok() { if (Pt->IsRunning()) Pt->exit(); delete Pt; }
|
|
|
11373
|
Qt / Общие вопросы / Re: connect сигналы и слоты=(
|
: Август 20, 2009, 19:41
|
Здравствуйте, Сергей ... (тем более что moc немного исковеркал или если хотите "дополнил" C++). ...
Не знаю что Вы имеете ввиду. Лично для меня (новичка в Qt) все эти moc и qmake пока больше геморрой чем выгода. Да, это сэкономит мне сотню строк, но для меня это не великая проблема, руками напишу, не переломлюсь Но вот торопиться с выводами по-моему не стоит. Поюзаем, посмотрим, а дальше - жизнь покажет
|
|
|
11375
|
Qt / Общие вопросы / Re: Как унаследовать QHash
|
: Август 20, 2009, 18:28
|
Здравствуйте insert(interface->getTitle(), interface); // Правильно???
Просто интересно - шо это за синтаксис? Кто такой "b" и как/где он описан? Кто кого вызывает? Edit: перепутал, я у себя вижу insert(interface->getTitle(), interface); // Правильно??? Наверное это просто ошибка в отображении на web Все равно не пойму - чей insert?
|
|
|
11376
|
Qt / Общие вопросы / Re: Слот-сигнал рекурс
|
: Август 20, 2009, 18:15
|
тут где-то было про замкнутый круг с сигналами.
Область для поиска, на память: Пользователь: "nixman" либо "panter_dsd" Тема: о календарях (виджет с 12 календарями) Суть: при переключении месяца одного календаря остальные должны обновиться
Спасибо, Юра, нашел (panter_dsd). Нужен класс - значит нужен. Понимаю - везде так и глупых претензий не имею
|
|
|
11377
|
Qt / Общие вопросы / Слот-сигнал рекурс
|
: Август 20, 2009, 17:15
|
Добрый день Осваиваю понемногу ихний слот-сигнал механизм Мне надо чтобы 2 QSplitter сайзились синхронно: пользователь двигает верхний - нижний вслед за ним, и наоборот. Сделал по букварю, нормально. Но получается что 2 QSplitter бесконечно посылают сигналы друг другу. Решил так: class CLinkSplitter : public QSplitter { Q_OBJECT
public: CLinkSplitter( QWidget * parent = 0 ) : QSplitter(parent) {}
private slots: void handleMoved( int pos, int index ) { bool state = blockSignals(true); moveSplitter(pos, index); blockSignals(state); } };
Вопрос(ы): верно ли я мыслюсь или есть что-то лучше/проще? Можно ли сделать то же, но не создавая новый класс только для этого? Спасибо
|
|
|
11378
|
Программирование / С/C++ / Re: Почему не срабатывает блок try?
|
: Август 20, 2009, 14:28
|
if (ptr) ptr->doSomething(); Делаю: if (ptr) printf("валидный указатель"); else printf("Не валидный указатель"); delete ptr; printf(Удалили); При ptr=NULL получаю: Не валидный указатель Удалили При ptr указывающий на самоудалившийся процесс, получаю: валидный указатель И все, сообщение "Удалили" я не получаю, программа вылетает на delete ptr. Как мне проверить, объект удален из памяти или нет? В программе с Qt ptr указывает на процесс. Если Вы имеете указатель, то Вы же и ответственны за его корректность, язык в этом никак помочь не может. Стандартный подход: немедленно обнулить указатель после delete delete(ptr); ptr = 0; Чтобы полностью исключить его дальнейшее использование. Любые действия с уже удаленным указателем ведут к очень тяжелым последствиям (просто вылет = самое лучшее из них). Ваш текст будет работать как Вы описали если, например, если вы вызвали delete второй раз для того же указателя. Использование exception в данном случае ничего не даст а только запутает: ptr может быть "корректным адресом" но данные по этому адресу уже разрушены, хуже того - этот адрес может уже используется для совершенно других данных. Чтобы найти ошибку надо смотреть все что делается с указателем начиная с его создания (обычно new). Это может быть очень непросто но других методов нет.
|
|
|
11379
|
Qt / Общие вопросы / Re: Удаление классов в Qt
|
: Август 19, 2009, 17:20
|
Обоснуй пункт 2
Зы Как уже писалось выше классы унаследованые от QObject уже с виртуальным деструктором
Но этого никак не видно без лазания по h файлам И чем держать это в памяти, для меня лучше написать virtual и быть уверенным что любое delete (хоть из parent хоть как) такой деструктор позовет.
|
|
|
11380
|
Программирование / Алгоритмы / Re: Выбор кандидата для деления
|
: Август 19, 2009, 13:10
|
П.С. Кстати, триангуляцию полигона ты тоже сам с нуля разработал? Нет такой задачи "триангуляция полигона" - это я для наглядности так сказал Если простые полигоны (3 или 4 вертекса) то надо говорить о триангуляции поверхности (часто называют mesh), разбивать ребра и делать новые полигоны из них. Если N-sided полигон - то это триангуляция контура (часто с font'ами). Этим тоже приходилось заниматься. Конечно, не с нуля. Обычно сначала погуглил и полистал десяток pdf по теме. Исходники попадаются и бывают даже хорошие. Но "взять что-то готовое и прикрутить" мне лично ни разу не удалось. Это возможно но потом будет себе дороже
|
|
|
11381
|
Qt / Общие вопросы / Re: Удаление классов в Qt
|
: Август 17, 2009, 19:14
|
насколько правильно я освобождаю память?? А класс class Roszdrav в свою очередь вызывается в другом классе
1) Почему бы просто не написать LS theL(this); Т.е. просто локальная переменная вместо указателя. Деструктор вызовется автоматически при выходе из функции. 2) Если деструктор все-таки нужен - его объявление должно быть virtual. Edit: пардон, не увидел страниц 2 и 3 Ответил что уже отвечено
|
|
|
11382
|
Программирование / Алгоритмы / Re: Выбор кандидата для деления
|
: Август 17, 2009, 15:49
|
Если заменить селектор на массив и отсортировать его то получим одноуровневое Б+ дерево. Поздравляю с велосипедиком. C std::set ты можешь определить свой аллокатор (советую Boost.Pool) и не возится руками с управлением памяти. Ну а ежели память таки жмёт, то в priority_queue или make_heap/push_heap/pop_heap никаких лишних данных. Кстати твой алгоритм на них элементарно переписывается. Ну и если таки нравится всё самому, то я бы таки держал отсортированным и селектор и outList. Тогда их не нужно на каждом цикле проходить полностью. Ну, в знании стандартной библиотеки мне в Вами не тягаться Понимаю, что Вы бы сделали за час (если не меньше) то над чем я сидел несколько дней. Но зато я свой алгоритм знаю досконально, могу поручиться за скорость и не завишу от всяких has_iterator_debugging, _SECURE_SCL и т.п. На мой взгляд "изобретать велосипед" значит "думать своей головой" и ничего плохого в этом нет
|
|
|
11383
|
Программирование / Алгоритмы / Re: Выбор кандидата для деления
|
: Август 15, 2009, 14:50
|
Сделал, рассказываю 1) Данные: из стандартной библиотеки используем только функцию qsort. Работаем только списками. struct Polygon { Polygon * mNext; ..... }; Банальное добавление в список: p->mNext = listHead; listHead = p; 2) Алгоритм: на каждом шаге имеется селектор - N списков, каждый из которых сортирован по убыванию. Выбор кандидата осуществляется прямым перебором (на максимум) всех "голов" N списков. После выбора голова одного из списков продвигается, если NULL - пустой список удаляется из селектора. Разбитые полигоны линкуются в выходной список outList. Если выбранный кандитат имеет меньшую площадь чем максимальный в outList, то тогда сортируем outList, добавляем его в селектор, обнуляем outList и повторяем выбор кандидата. 3) Детали: а) сортировка списка - выделяем память под массив указателей - проходим по списку и заполняем массив указателей - сортируем массив указателей (qsort) - проходим по массиву и заполняем mNext - удаляем массив указателей б) Селектор: здесь можно использовать все что угодно, на мой вкус тоже список struct Selector { Selector * mPrev; Selector * mNext; Polygon * mHead; }; 4) Ну а не получится ли что N (число списков для выбора) будет расти и расти? Нет, практически N очень мало (я не смог достичь даже 10 ) Если площади всех полигонов одинаковы - то вообще 1 список который затем замещается новым. Если есть большие полигоны - то они быстро породят новые списки, но эти же списки первыми попадут под деление и будут быстро исчерпаны.
|
|
|
11384
|
Программирование / Алгоритмы / Re: Выбор кандидата для деления
|
: Август 14, 2009, 13:16
|
Бинарное сбалансированное с сортировкой по площади. Тот же std::set. Операции вставки и удаления не хуже чем log2 N. Очередь с приоритетами - тоже подойдёт - она, в сущности, тоже дерево. Алгоритм гарантирует, что разбиваемый полигон будет всегда наибольший. Ну, лучше уж сказать "STL гарантирует" Проверять не проверял но полагаю что по скорости он никак не лучше. С log2 N все в порядке, но ведь он позовет malloc при каждом добавлении в дерево и free при каждом удалении. А по памяти памяти просто хуже потому что сожрет байт 20 на каждый нод. Конечно, для игровых моделей (до 50K полигонов) все будет работать прекрасно. Но не там где память используется "до упора". Тут даже new надо использовать аккуратно, например polygon * p = new Polygon(); // нехорошо если полигонов действительно МНОГО polygon * p = new Polygon[POLY_CHUNK_SIZE]; // так лучше хотя потом прийдется написать немного больше
|
|
|
11385
|
Программирование / Алгоритмы / Re: Выбор кандидата для деления
|
: Август 13, 2009, 18:22
|
Поэтому необходимо как можно меньше сортировок больших массивов и меньше объединений с большим массивом, не надо добавлять в конец, а потом сортировать все вместе. Лучше добавлять в другой массив, и потом в нужный момент сортировать его и объединять с основным.
Хммм.... в этом что-то есть. У меня появилась идейка, сделаю - расскажу
|
|
|
|
|