Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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.034 c
1-1086928329
Softal
2004-06-11 08:32
2004.06.27
ListBox


14-1086759148
KilkennyCat
2004-06-09 09:32
2004.06.27
мой любимый анекдот (мож кто не слышал) :)


4-1084962403
uno
2004-05-19 14:26
2004.06.27
взять путь


1-1086775886
alexa
2004-06-09 14:11
2004.06.27
Изменение цвета в Memo


1-1086687898
SendeR
2004-06-08 13:44
2004.06.27
Неудалимая прога......





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский