Главная страница
    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.087 c
2-1343902126
Wadimka
2012-08-02 14:08
2013.03.22
Как запись типа record записать в TStream?


2-1338534766
leklerk
2012-06-01 11:12
2013.03.22
Вторичная форма в центре главной


15-1346016093
Artem
2012-08-27 01:21
2013.03.22
Не поможете с Visual C++?


2-1334555099
Мишан
2012-04-16 09:44
2013.03.22
Вот так бывает


15-1351761325
Игорь Шевченко
2012-11-01 13:15
2013.03.22
Кто, чем и как обрабатывает XML-файлы большого объема ?





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