![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Процедуры вылетают без ошибок
Krolm © (2008-11-05 06:52:00)В достаточно крупном приложении произвольно вылетают процедуры. То есть доходит до какой-то строчки, потом в подпрограмме при построковой отладке брейк прыгает на строчку end; и выходит из всех подпрограмм на самый высокий уровень. Никаках сообщений об ошибках. Если есть try finally блоки - finally обрабатывается нормально.
Типичные процедуры, после которых вылетает:
s:=StringReplace(s,#13#10,#9,[rfReplaceAll]);
sl.add(s); (sl:TstringList);
При этом если такие "проблемные" процедуры заменить на другие попроще, например MessageBox(0,@s[1],'',0); Все отрабатывается без проблем.
Сначала помогло увеличение размера стека + директива компилятора inline. Поток стал отрабатывать без проблем. Но такая же ерунда возникла в основной программе, в процедуре сохранения StringGrid в файл. Не могу найти причину. Что может быть?
ОС Vista, CodeGear™ RAD Studio 2007 Version 11.0.2902.10471
MsGuns (2008-11-07 15:00:00) [1]>Krolm © (06.11.08 15:20) [24]
>Нет сортировки, нет фильтрации. Это самое важное. Сортировку еще могу реализовать. Но как >фильтрацию сделать - даже и не знаю.
Все делается элементарно, если использовать сетку только для отображения, а сами данные хранить в структурах (классах, рекордах,БД) списками. Списки можно и сортировать и фильтровать, а в сетку "передавать" только список отображаемых. Грид куда быстрее перерисует новый список, чем, например, будет менять местами строки, например, при сортировке.
KSergey (2008-11-06 16:11:00) [2]> Vlad Oshin © (06.11.08 15:35) [28]
> есть идея второй grid поверх первого держать, второй слой как-бы.
ТОгда навероне будет правильнее все ж отдельный контейнер сделать, а не использовать грид не по делу :)
Vlad Oshin (2008-11-06 15:35:00) [3]
> как фильтрацию сделать
есть идея второй grid поверх первого держать, второй слой как-бы.
И показывать его и в нем то, что удовлетворяет фильтру из первого
Anatoly Podgoretsky (2008-11-06 15:28:00) [4]> Krolm (06.11.2008 14:13:20) [20]
По делу пожинаешь. В моих программ единственный посторонний компонент - это TntUnicode - по острой необходимости.
Anatoly Podgoretsky (2008-11-06 15:27:00) [5]> Krolm (06.11.2008 12:43:18) [18]
Ни какой мистики.
В тех случая когда не происходить нарушения, то есть память еще принадлежит твоему приложению, и она еще не порушена, а показывает на еще не существующий кусок или уже занятый другим экземпляром.
Подобный вопрос часто задают - как узнать разрушен компонент или нет. Обсуждения обычно длинные.
Сергей М. (2008-11-06 15:26:00) [6]
> Krolm © (06.11.08 15:20) [24]
А откуда вообще у тебя берутся данные, визуализируемые гридом ?
Krolm (2008-11-06 15:20:00) [7]Нет сортировки, нет фильтрации. Это самое важное. Сортировку еще могу реализовать. Но как фильтрацию сделать - даже и не знаю.
Сергей М. (2008-11-06 14:56:00) [8]
> Написать самому такое - уйдут недели
А чем собссно StringGrid не угодил ?
Krolm (2008-11-06 14:47:00) [9]Уже. Сижу мучаюсь( Повыкидывал из него много лишнего)) Ну для меня не нужного типа настроек шрифтов для каждой ячейки.
Сергей М. (2008-11-06 14:19:00) [10]Тогда смело раскомментируй
Krolm (2008-11-06 14:13:00) [11]Я написал что это не StringGrid а SortGrid. Компонент взят с торри. Написать самому такое - уйдут недели. Вот пожинаю плоды своей лени.
Сергей М. (2008-11-06 13:05:00) [12]
> Мне страшно раскоментировать эту строчку
В D7 (build 8.1) и в Grids и в QGrids строчка, на которой ты сделал акцент, не закомментирована ..
Krolm (2008-11-06 12:43:00) [13]Казалось) Все приходит с опытом. Анатолий, Вы как специалист может расскажете о том, в каки случаях Access Violation не возникает? Какие-нибудь примеры? Мне например будет интересно изучить этот вопрос.
Anatoly Podgoretsky (2008-11-06 11:07:00) [14]В том то и дело, что тебе только кажется.
Krolm (2008-11-06 10:54:00) [15]Все хватит флейм разводить. Что там компилятор должен или не должен.
2KSergey дело не в проверках каждого байта. Мне раньше казалось, что обращение к несуществующему объекту обязательно должно провоцировать ошибку. Разве не так? А если уж за пределами памяти своего приложения- тогда вообще ОС должна ругаться что приложение недопустимую операцию осуществляет. Тут видимо ситуация именно со стеком была, с учетом того, что увеличение его размера позволило нормально отрабатывать потоку.
Анатолий, каждый программист допускает ошибки. Называть это глупостью нехорошо. В противном случае все программисты заранее глупы. Мы люди, а не машины. Ради интереса опять написал свою ошибку в код и прогнал программу со включенным RangeCheck ом. Никакой ругани.
Нехорошо поступил разработчик компонента TSortGrid, который сделал так:
procedure InvalidOp(const id: string);
begin
// raise EInvalidGridOperation.Create(id);
end;
procedure TMyCustomGrid.SetColWidths(Index: Longint; Value: Integer);
begin
if FColWidths = nil then
UpdateExtents(FColWidths, ColCount, DefaultColWidth);
if Index >= ColCount then InvalidOp(SIndexOutOfRange);
if Value <> PIntArray(FColWidths)^[Index + 1] then
begin
ResizeCol(Index, PIntArray(FColWidths)^[Index + 1], Value);
PIntArray(FColWidths)^[Index + 1] := Value;
ColWidthsChanged;
end;
end;
Хороший подход к созданию безглючных компонентов)) Мне страшно раскоментировать эту строчку)
KSergey (2008-11-06 10:21:00) [16]Память не выделяется побайтно, да и не может компилятор встраивать код проверки каждого байтика: допустимо его (байтика) использование программистом или нет. Это слишком накладно и затратно было бы в плане ресурсов и производительности.
А потому обращение к произвольному участку памяти не всегда недопустимо: возможно эта память находится в блоке, который вообще-то данному приложению доступен с точки зрения ОС, однако память эта заполнена мусором. Ну либо вообще шарахаемся по собственному стеку: тогда получается операции с памятью приложению разрешены, однако понятно, что ничего доброго из этого не получится. Обработка исключений - она тоже ведь вовсе не "неубиваемая".
(впрочем, переходи на .NET - тама подобные засады решены в ядре + компиляторе, причем неотключаемо, если только не пытаться "обмануть" компилятор специально).
Anatoly Podgoretsky (2008-11-06 08:51:00) [17]> Krolm (06.11.2008 8:33:11) [11]
Не кати бочку на компилятор, сглупил ты, компилятор честно выполнил твои пожелания.
Anatoly Podgoretsky (2008-11-06 08:50:00) [18]> Krolm (06.11.2008 8:31:10) [10]
Потому, что ты начинающий и до тебя пока не доходит необходимость настройки компилятора на предмет проверки выхода за границы (Range checking).
Сергей М. (2008-11-06 08:42:00) [19]
> Krolm © (06.11.08 08:31) [10]
> Никаких исключительных ситуаций не возникает
Значит в утверждении
> Типичные процедуры, после которых вылетает:
> s:=StringReplace(s,#13#10,#9,[rfReplaceAll]);
> sl.add(s); (sl:TstringList);
>
> При этом если такие "проблемные" процедуры заменить на другие
> попроще, например MessageBox(0,@s[1],'',0); Все отрабатывается
> без проблем.
>
нет ни слова истины
Krolm (2008-11-06 08:33:00) [20]Надо было включить RangeCheck короче, и было бы все намного проще. Хотя почему никакой ошибки ReadofAddress не возникало, для меня до сих пор загадка. Компилятор получается сглупил?