Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

Ошибка Access violation... и странный указатель   Найти похожие ветки 

 
ПЛОВ ©   (2012-07-12 15:26) [0]

Народ, подскажите, куда копать для поиска причин таких ошибок?
Есть обычный односвязный динамический список указателей, состоящий из элементов типа

 PDataListItem = ^TDataListItem;

 TDataListItem = record
   Data: Pointer; // Data
   NextItem: PDataListItem; // Next item
 end;

и оформленный в виде класса. Был тестен-перетестен.

Сейчас юзаю его в программе, выбирают из БД записи, загоняю их в список (в виде объектов), после чего данные из этого списка добавляются в ListView.
Все записи в ListView попадают, ошибок нет.
Но! При обновлении списка (опять загрузка из БД - список - ListView) вылетает ахис виолейшен. Конкретно - в процедуре очистки списка, вот она:
// -- Clear list --
procedure TDataList.Clear;
var
 CurrItem: PDataListItem;
 Item: PDataListItem;

 RRR: Integer;

begin
 RRR := 0;

 if FStartDataListItem <> nil then  
 begin
   Item := FStartDataListItem;

   while Item^.NextItem <> nil do  // <<<< ТУТ!
   begin
     CurrItem := Item^.NextItem;
     Item := Item^.NextItem;

     if Assigned(FOnRemoveItem) then FOnRemoveItem(Self, CurrItem^.Data);
     Dispose(CurrItem);

     Inc(RRR);
   end;

   CurrItem := FStartDataListItem;

   if Assigned(FOnRemoveItem) then FOnRemoveItem(Self, CurrItem^.Data);
   Dispose(CurrItem);

   FStartDataListItem := nil;
 end;
end;


Смотрю в отладчике и вижу такое:

Item = $40959F0
   Data = Inaccessible value
   NextItem = Inaccessible value


Это капец, как такое может быть, ведь список прочитался. Проявляется на записи в середине списка, она и не последняя, и не первая :( Причем ошибка "плавающая", т.е. иногда возникает, иногда нет...


 
Palladin ©   (2012-07-12 15:32) [1]

while Item^.NextItem <> nil do  // <<<< ТУТ!

Item - содержит мусор или указатель на освобожденный блок


 
Palladin ©   (2012-07-12 15:35) [2]

while Item^.NextItem <> nil do  // <<<< ТУТ!
   begin
     CurrItem := Item^.NextItem; - запонил NextItem
     Item := Item^.NextItem; - еще раз запомнил NextItem

     if Assigned(FOnRemoveItem) then FOnRemoveItem(Self, CurrItem^.Data);
     Dispose(CurrItem); - освободил память, теперь Item указывает в освобожденный блок

     Inc(RRR);
   end;


 
Palladin ©   (2012-07-12 15:37) [3]

Плавающая потому что данные в освобожденном блоке вполне могут жить и дальше некоторое время. По встречке тоже ездить можно.


 
RWolf ©   (2012-07-12 15:42) [4]

вообще, зачем строить цикл на Item^.NextItem, разве не проще следить непосредственно за Item? и начало списка освобождать отдельно не придётся.


 
ПЛОВ ©   (2012-07-12 15:49) [5]

Спасибо за помощь! :) Кажись понял, буду переделывать свою писанину :)


 
ПЛОВ ©   (2012-07-12 15:51) [6]

разве не проще следить непосредственно за Item?

Вроде:
читаем в Item начало списка, проверяем его на nil - если нет, ставим в начало NextItem, а Item освобождаем?


 
Palladin ©   (2012-07-12 16:07) [7]

  while Item <> nil do
   begin
     CurrItem := Item;
     Item := Item^.NextItem;

     if Assigned(FOnRemoveItem) then FOnRemoveItem(Self, CurrItem^.Data);
     Dispose(CurrItem);

     Inc(RRR);
   end;


 
Palladin ©   (2012-07-12 16:13) [8]

и вообще, лишних движений многовато

procedure TDataList.Clear;
var
 CurrItem: PDataListItem;

begin
   while FStartDataListItem <> nil do
   begin
     CurrItem := FStartDataListItem;
     FStartDataListItem := FStartDataListItem^.NextItem;

     if Assigned(FOnRemoveItem) then
       FOnRemoveItem(Self, CurrItem^.Data);
     Dispose(CurrItem);
   end;
end;


и всего делов


 
MsGuns ©   (2012-07-12 16:13) [9]

А почему нельзя пользоваться рабоче-крестьянским TList ?


 
ПЛОВ ©   (2012-07-12 16:15) [10]

Ага, спасибо! )


 
ПЛОВ ©   (2012-07-12 16:22) [11]

Можно и TList-ом, но я решил изобрести велосипед :)


 
Dennis I. Komarov ©   (2012-07-12 21:35) [12]


> ПЛОВ ©   (12.07.12 15:26) 
>

Иш ты какие люди появляются :)



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.126 c
2-1337757624
well
2012-05-23 11:20
2013.03.22
Как вывести сообщение об ожидании выполнения операции?


15-1328778076
БарЛог
2012-02-09 13:01
2013.03.22
Удаление сообщений, удаление имен на форуме


15-1354292775
Очень Злой
2012-11-30 20:26
2013.03.22
Оптимизировать код


15-1340224203
Юрий
2012-06-21 00:30
2013.03.22
С днем рождения ! 21 июня 2012 четверг


2-1338107276
rikitiki2012
2012-05-27 12:27
2013.03.22
Автоматически прерывает выполнение (BreakPoint в настройках )





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский