OK, problem jest trochę skomplikowany, ale szukałem wcześniej wycieków pamięci i nie znalazłem niczego niepokojącego. Zapewnię też, że nie zrobiłem żadnego głupiego błędu w stylu "za mała tablica dynamiczna", czy też odwołanie do nieistniejącego elementu.
Więc oto jest problem.
Mam tablicę dynamiczną, której elementy składają się z kilku pól, m.in. PluginInfo.
Typ TPluginInfo to zwykły typ rekordowy.
I teraz tak, pobieram sobie zawartość rekordu z dllki i przypisuję ją właśnie do tego:
var
pInfo: PPluginInfo;
begin
new(pInfo);
Plugin.IFace.GetPluginInfo(pInfo); //pobranie z dllki do pInfo
with Plugin.PluginInfo do
begin
GetMem(Name, length(pInfo^.Name)+1);
Name:=StrCopy(Name, pInfo^.Name);
GetMem(Author, length(pInfo^.Author)+1);
Author:=StrCopy(Author, pInfo^.Author);
Year:=pInfo^.Year; //typ word
GetMem(www, length(pInfo^.www)+1);
www:=StrCopy(www, pInfo^.www);
GetMem(AddInfo, length(pInfo^.AddInfo)+1);
AddInfo:=strCopy(AddInfo, pInfo^.AddInfo);
version:=pInfo^.version; //typ double
end;
dispose(pInfo);
end;
Oczywiście łańcuchy to typ PChar.
Nie muszę robić przypisania w taki sposób, ale, gdy robię inaczej(np. Name:=pInfo^.Name), to wtedy po zwolnieniu biblioteki pole wskazuje na nieprawidłowy adres.
Problem pojawia się w momencie zwalniania tej pamięci:
//robię to w pętli oczywiście
Plugins[i].PluginInfo.Name:=nil;
Plugins[i].PluginInfo.Author:=nil;
Plugins[i].PluginInfo.www:=nil;
Plugins[i].PluginInfo.AddInfo:=nil;
//i na koniec, jakby się ktoś pytał - poza pętlą:
plugins:=nil;
Próbowałem na początku FreeMem zamiast nilowania PCharów, ale efekt był podobny.
A mianowicie Access Violation podczas plugins:=nil(konkretnie @DynArrayClear - w oknie CPU). Jeśli rezygnuję z plugins:=nil, to wtedy AV występuje w innym miejscu(np. przy określaniu wielkości tablicy Plugins).
Czy ktoś jest w stanie mi powiedzieć, co tu jest nie tak?
I tak, próbowałem Finalize(kompilator to w ogóle wywalił) i próbowałem new i dispose, ale wtedy dostałem mnóstwo wyjątków podczas tworzenia zmiennej addInfo.
I jeszcze coś, co może mieć wpływ:
tablica jest tworzona w procedurze A, getMem w metodzie B, a FreeMem, znów w procedurze A.
[ROZWIĄZANE]
OK problem był w nieco innym miejscu. Podczas łączenia się z pluginem inicjalizuję interfejs, który jest mostem między aplikacją, a pluginem właśnie. I chodziło o to, że na koniec muszę ten interfejs nilować.