Форум: "Потрепаться";
Текущий архив: 2004.06.27;
Скачать: [xml.tar.bz2];
ВнизПлавающее Access Violation Найти похожие ветки
← →
Andrey007 (2004-06-09 09:45) [0]У меня Access Violation выскакивал при выполнении следующего куска кода.
if (Areas<>nil) and (Areas.Count>0) then for i:=0 to Areas.Count-1 do
try
if (TVRTimes(Areas.Items[i]).times<>nil) and (TVRTimes(Areas.Items[i]).times.Count>0) then
// вот на этом if как раз и выскакивал Access Violation
for j:=0 to TArea(Areas.Items[i]).times.Count-1 do
begin
if TVRTime(TVRTimes(Areas.Items[i]).times[j]).beg<beg
then beg:=TVRTime(TVRTimes(Areas.Items[i]).times[j]).beg;
if TVRTime(TVRTimes(Areas.Items[i]).times[j]).en>en
then en:=TVRTime(TVRTimes(Areas.Items[i]).times[j]).en
end;
except
end;
Эта процедура у меня стоит в методе класса. Я проверял правильность преобразования типов - всё правильно, выход за границы списка - ошибка вываливалась на первом же элементе списка (в смысле, на элементе списка с номером ноль).
В отладчике по Ctrl+F7 когда проверяю TVRTimes(Areas.Items[i]).times=nil, выдавался результат - False, а когда хотел посмотреть TVRTimes(Areas.Items[i]).times.Count, то выдвалось DelphiException. То же самое и когда хотел посмотреть TVRTimes(Areas.Items[i]).times.ClassName. (Этот times на самом деле TObjectList)
Ничего так и не надумал, решил заняться этим на следующий день. А сегодня всё работает нормально. У кого так было? В чём может быть дело?
← →
Тимохов © (2004-06-09 09:46) [1]значит какой-то items[i] равен nil
← →
Тимохов © (2004-06-09 09:48) [2]за except end убивать надо...
← →
Polevi © (2004-06-09 09:48) [3]Assigned(Areas.Items[i]) ?
← →
Anatoly Podgoretsky © (2004-06-09 09:52) [4]Вот это может дать ошибку в зависимости от настроек
if (Areas<>nil) and (Areas.Count>0) then for i:=0 to Areas.Count-1 do
Можно написать так
if (Areas<>nil) then for i:=0 to Areas.Count-1 do
И в других местах аналогично
← →
Danilka © (2004-06-09 09:54) [5]procedure TForm1.Button1Click(Sender: TObject);
var
sl: TStringList;
begin
sl:=TStringList.Create;
sl.Free;
if Assigned(sl) then ShowMessage("Assigned");
if sl <> nil then ShowMessage("not nil");
ShowMessage(IntToStr(sl.Count)); // получим по-башке
end;
← →
Danilka © (2004-06-09 09:56) [6]Это я вот к этому:
> TVRTimes(Areas.Items[i]).times=nil, выдавался результат
> - False, а когда хотел посмотреть TVRTimes(Areas.Items[i]).times.Count,
> то выдвалось DelphiException
← →
panov © (2004-06-09 09:59) [7]>Тимохов © (09.06.04 09:48) [2]
за except end убивать надо...
Неправда. Это нормальная ситуация - подавление Exception.
← →
Тимохов © (2004-06-09 10:02) [8]
> panov © (09.06.04 09:59) [7]
надо не давать, а обрабатывать...
имхо конечно, но думаю, многие согласятся...
← →
Тимохов © (2004-06-09 10:04) [9]
> panov © (09.06.04 09:59) [7]
вернее так - давить исключения можно, но не все же.
AV точно нельзя давить, т.к. это может привести к совершенно жутким последствиям...
← →
vecna © (2004-06-09 10:51) [10]согласен с Тимохов,
(TVRTimes(Areas.Items[i]).times.Count>0)
Assigned(times) ?
← →
Andrey007 (2004-06-09 10:57) [11]> Тимохов ©
> значит какой-то items[i] равен nil
Как может быть Areas.Items[i] равен nil если TVRTimes(Areas.Items[i]).times не равен nil?
> за except end убивать надо...
Если Вы посмотрите исходники VCL, то увидите там except end не раз и не два.
> Anatoly Podgoretsky © (09.06.04 09:52) [4]
> Вот это может дать ошибку в зависимости от настроек
А какие настройки Вы имеете в виду?
← →
KSergey © (2004-06-09 10:58) [12]> [7] panov © (09.06.04 09:59)
> Неправда. Это нормальная ситуация - подавление Exception.
Что-то я вас не понял, в контексте вопроса...
← →
KSergey © (2004-06-09 10:59) [13]> [11] Andrey007 (09.06.04 10:57)
> А какие настройки Вы имеете в виду?
Вероятно эти:
{$B-}
{$B+}
Ну или соотв. опции проекта
← →
KSergey © (2004-06-09 11:01) [14]> [11] Andrey007 (09.06.04 10:57)
> Если Вы посмотрите исходники VCL, то увидите там except
> end не раз и не два.
Да, но если бы узнать мотивы, двигавшие вами в написании этого - можно было бы скаать правомочно это или нет в данном случае. И есть у меня нехорошие подозрения, что... см. [9] Тимохов © (09.06.04 10:04)
← →
Andrey007 (2004-06-09 11:04) [15]Я заменил begin ... end на try ... except end после того, как стало выскакивать Access Violation.
← →
Тимохов © (2004-06-09 11:04) [16]
> Andrey007 (09.06.04 10:57) [11]
> > Тимохов ©
> Как может быть Areas.Items[i] равен nil если TVRTimes(Areas.Items[i]).times
> не равен nil?
запросто.
← →
Тимохов © (2004-06-09 11:05) [17]
> Andrey007 (09.06.04 11:04) [15]
> Я заменил begin ... end на try ... except end после того,
> как стало выскакивать Access Violation.
браво.
решение достойное королей софтверного бизнеса...
:)))
← →
Игорь Шевченко © (2004-06-09 11:06) [18]panov © (09.06.04 09:59)
> Неправда. Это нормальная ситуация - подавление Exception.
Ничего, кроме головной боли, это подавление не приносит.
Тимохов © (09.06.04 09:48) [2] абсолютно прав.
← →
Danilka © (2004-06-09 11:06) [19][10] vecna © (09.06.04 10:51)
Я привел пример, когда Assigned будет возвращать true, когда ссылка будет не равна nil, и при этом самого объекта уже не будет.
Скорее всего, этот вариант и имел место быть - объект создали, затем прибили, а ссылку не обнулили.
← →
Тимохов © (2004-06-09 11:08) [20]
> Andrey007 (09.06.04 10:57) [11]
> Как может быть Areas.Items[i] равен nil если TVRTimes(Areas.Items[i]).times
> не равен nil?
>
> > за except end убивать надо...
еще вариант (как пишет Danilka) - не равен nil, но указывает на давно (или недавно) удаленный объект, т.е. указывает фиг знает куда... иногда это будет работать, иногода нет. поэтому и нерегулярность возникновения ошибки.
← →
Andrey007 (2004-06-09 11:12) [21]> Danilka ©
> Скорее всего, этот вариант и имел место быть - объект создали, затем прибили, а ссылку не обнулили.
Прикол в том, что этот код вызывается из FormCreate формы, которая создаётся при запуске программы. То есть это первое исполнение этого кода - проверял, устанавливая там точку останова перед запуском программы.
← →
Anatoly Podgoretsky © (2004-06-09 11:14) [22]В контексте вопроса, если бы тихо не было подавлено исключение, то возможно было бы осмысленное сообщение и возможно на более ранней стадии не доходя до AV
← →
Danilka © (2004-06-09 11:20) [23]
> Прикол в том, что этот код вызывается из FormCreate формы
Да хоть где.
Откуда-то берется и сам Areas, и его итемсы. Если они создаются здесь-же, в этой-же процедуре, и не прибиваются до этого кода, то и смыла нет проверять их на то, созданы они или нет, равны ли nil или нет.
← →
Andrey007 (2004-06-09 11:27) [24]> Anatoly Podgoretsky © (09.06.04 11:14) [22]
> В контексте вопроса, если бы тихо не было подавлено исключение, то возможно было бы осмысленное сообщение и возможно на более ранней стадии не доходя до AV
Дело в том, что AV выскакивало при запуске программы из Delphi и никаких предшествующих сообщений не было. В отладчике у меня стоит галка "Stop on Delphi Exceptions".
> Danilka © (09.06.04 11:20) [23]
> Да хоть где.
> Откуда-то берется и сам Areas, и его итемсы. Если они создаются здесь-же, в этой-же процедуре, и не прибиваются до этого кода, то и смыла нет проверять их на то, созданы они или нет, равны ли nil или нет.
Сначала создаётся Areas (TObjectList), потом элементы, которыми он наполняются, потом эти элементы заталкиваются в него, и потом вызывается обсуждаемый кусок кода.
← →
Тимохов © (2004-06-09 11:30) [25]
> Andrey007 (09.06.04 11:27) [24]
чую вы дозреваете потихонечку до мысли, что так вам никто ничего дельного не скажет и что нужно бы больше кода привести.
← →
Danilka © (2004-06-09 11:32) [26][24] Andrey007 (09.06.04 11:27)
Тогда какой смысл вообще проверять: Areas<>nil, если он здесь-же создается?
И какой смысл проверять элементы?
Если проверяешь, значит есть вероятность, что объекты больше не существуют, так?
← →
BzionWar (2004-06-09 11:34) [27]Все таки попробуйте
Anatoly Podgoretsky © (09.06.04 09:52) [4]
У меня как-то раз был почти такой же случай. Помогло именно то, что посоветовал АП.
Точнее, я разделил условие проверки на nil и следующее сравнение.
← →
Mystic © (2004-06-09 12:49) [28]
> надо не давать, а обрабатывать...
> имхо конечно, но думаю, многие согласятся...
Если нужно подавить исключение, я использую вместо try except end конструкцию:try
except
on E: EAbotCalculation do;
end;
← →
Тимохов © (2004-06-09 12:56) [29]
> Mystic © (09.06.04 12:49) [28]
во, именно это я и имею в виду - подавлять надо только то, что вы своим разумом знаете подавлять надо и можете точно объяснить зачем это нужно делать. Подавать все - непростительно...
← →
Andrey007 (2004-06-09 13:18) [30]> Danilka © (09.06.04 11:32) [26]
> Тогда какой смысл вообще проверять: Areas<>nil, если он здесь-же создается?
В том классе, у которого есть это свойство, Areas может быть равен nil. Я не совсем правильно выразился в прошлый раз - тогда я имел в виду конкретную ситуацию, когда Areas всё-таки создавался. А в принципе он может и не создаваться. Тогда он nil.
> И какой смысл проверять элементы?
> Если проверяешь, значит есть вероятность, что объекты больше не существуют, так?
Да. Если бы ошибка не выскакивала, я бы и не ставил проверки.
В общем, тот кусок я переделал вот так:
if (Areas<>nil) and (Areas.Count>0) then for i:=0 to Areas.Count-1 do
if (Areas.Items[i]<>nil) and (TVRTimes(Areas.Items[i]).times<>nil) and
Assigned(TVRTimes(Areas.Items[i]).times) and
(TVRTimes(Areas.Items[i]).times.Count>0) then
for j:=0 to TArea(Areas.Items[i]).times.Count-1 do
begin
if TVRTime(TVRTimes(Areas.Items[i]).times[j]).beg<beg
then beg:=TVRTime(TVRTimes(Areas.Items[i]).times[j]).beg;
if TVRTime(TVRTimes(Areas.Items[i]).times[j]).en>en
then en:=TVRTime(TVRTimes(Areas.Items[i]).times[j]).en
end;
При этом в опциях компилятора у меня не стоит галка "Complete boolean eval", а в проекте директивы {$B+} нигде нет.
← →
KSergey © (2004-06-09 13:24) [31]> А в принципе он может и не создаваться. Тогда он nil.
А уверенность в этом есть? ЧТо он именно nil, если не создался??
> [15] Andrey007 (09.06.04 11:04)
> Я заменил begin ... end на try ... except end после того,
> как стало выскакивать Access Violation.
Вот это я и подозревал... и не я один...
Но как же хочется услышать начальника транспортного цеха!
← →
Anatoly Podgoretsky © (2004-06-09 13:28) [32]Дело даже не в директива, при нулевой длине будет for I := 0 to -1 и цикл точно также не будет исполняться, но зато не будет возможности для ошибки при разном вычислении выражения.
Кроме того не гарантируется порядок вычисления, дело компилятора. Но в случае не полного вычисления слева направо с учетом приоритетов.
← →
Andrey007 (2004-06-09 13:28) [33]> KSergey © (09.06.04 13:24) [31]
> А уверенность в этом есть? ЧТо он именно nil, если не создался??
Вот конструктор того класса, которому принадлежит Areas:
constructor TVR.Create;
begin
inherited Create;
Areas:=nil;
// и прочая
...
end;
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.06.27;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.031 c