Witam. Pisząc wczoraj pewien program, do odczytu pewnego pliku natrafiłem na dość nietypowy problem. Chcąc dokładnie opisać mój problem , najpierw postaram się po krótce przedstawić specyfikacje pliku. Pierwsze co, nagłówek który liczy 40 bajtów, prócz pewnych danych które zawiera jest czterobajtowa wartość przedstawiająca liczbe poniższych wpisów, czy rekordów jak kto woli. Okay, odczytałem. Czas teraz odczytać zawarte tam rekordy. Każdy rekord składa się, z łańcucha znaków oraz dziesięciu wartościzmienno-przecinkowych. I tutaj zaskoczyło mnie to że długość łańcucha znaków(każdego rekordu), to również 4-bajtowa wartość, a nie 1 bajt jak to jest np przy String. Zatem pomyślałem że dynamiczna tablica char'ów, załatwi sprawę. Po długości łańcucha i samym łańcuchu jest wspomniane wcześniej 10 wartości zmienno przecinkowych które zamykam w 3 rekordach, jak widać poniżej.
Pierw przedstawie deklaracje:
type OPLHeader = packed record
CRC: LongWord; //Wiadomo...
Crap: array[5..36] of Byte; //Tej części nagłówka nie znam, więc zamykam w tablicy.
ItemCount: LongWord; //Tu ilość rekordów...
end;
type OPLPosition = packed record
x : Single;
y : Single;
z : Single;
end;
type OPLRotation = packed record
x : Single;
y : Single;
z : Single;
w : Single;
end;
type OPLScale = packed record
x : real;
y : real;
z : real;
end;
Tu mamy zaś strukture wpisów:
Type OPLRecord = packed record
PathLength: LongWord; //długość łańcucha znaków
ObjectPath: Array of Char; //łańcucha znaków
Position: OPLPosition; //
Rotation: OPLRotation; // <- wiadomo
Scale: OPLScale; //
end;
Oraz zmienne na których operuje:
Header: OPLHeader;
Items: array of OPLRecord;
Tutaj zaprezentuje kod, po napisaniu którego, stanąłem w miejscu.
procedure TOPL.LoadFromFile(Filename: String);
var
PathChar: Byte;
begin
Assign(F,Filename);
Reset(F,1);
//czytam nagłówek//
BlockRead(F,Header,SizeOf(Header));
//Rozmiar tablicy Items będzie równa ilości wpisów w pliku (z nagłówka)
SetLength(Items,Header.ItemCount);
//Od początku do końca...
for i:= Low(Items) to High(Items) do
begin
//Odczytuje dlugosc lancucha
BlockRead(F,Items[I].PathLength,4);
//Ustawiam długość łańcucha
SetLength(Items[i].ObjectPath,Items[I].PathLength);
//Czytam łańcuch
for PathChar:=Low(Items[i].ObjectPath) to High(Items[i].ObjectPath) do
begin
BlockRead(F,Items[i]. ObjectPath[PathChar],1);
end;
//Czytam pozostały stuff...
BlockRead(F,Items[i].Position,SizeOf(Items[i].Position));
BlockRead(F,Items[i].Rotation,SizeOf(Items[i].Rotation));
BlockRead(F,Items[i].Scale,SizeOf(Items[i].Scale));
end;
//Koniec... po imprezie :)
CloseFile(F);
end;
Okay... Co w taim razie jest tu problemem? Otóż to że po wywołaniu LoadFromFile, moja aplikacja nieodpowiada, a nawet czasem wysypie sie delphi przy okazji... Próbowałem znaleŹć przyczyne, i zauważyłem że jak zakomentuje
//Ustawiam długość łańcucha
//SetLength(Items[i].ObjectPath,Items[I].PathLength);
program działa, choć wiadomo, czyta nie tak jak powinien...
Nie raz korzystałem z dynamicznych tablic, a z taką sytuacją stykam się pierwszy raz. Niewiem, może to przez to że to tak naprawde dynamiczna tablica w dynamicznej tablicy? Nie mam pojęcia, i tu licze na pomoc z waszej strony.
Z góry dziękuje.