Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Ошибка 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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.086 c
3-1281098029
Patrick
2010-08-06 16:33
2013.03.22
Связанные сервера Oracle


15-1335360956
Программист Максим
2012-04-25 17:35
2013.03.22
Посоветуйте HTML-PHP-CSS-JavaScript редактор.


15-1330968658
asail
2012-03-05 21:30
2013.03.22
Ну вот что за гады?


15-1354393802
Юрий
2012-12-02 00:30
2013.03.22
С днем рождения ! 2 декабря 2012 воскресенье


15-1340687560
AV
2012-06-26 09:12
2013.03.22
Что то пропустил, как так можно делать?