Главная страница
    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.073 c
15-1351562934
Вепрь
2012-10-30 06:08
2013.03.22
UUID Компьютера.


2-1337847952
Bojo
2012-05-24 12:25
2013.03.22
Сократить код


15-1338965289
alexdn
2012-06-06 10:48
2013.03.22
Таблицу в пхп


15-1337202631
Германн
2012-05-17 01:10
2013.03.22
Подскажите инструмент


2-1333196241
SKIPtr
2012-03-31 16:17
2013.03.22
управление входящим подключением





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