konto usunięte

Temat: Tablice dynamiczne w Turbo Delphi

Weźmy taki fragment kodu:

var
tab: array of Byte;
stream: TFileStream;

begin
SetLength (tab, 100);
// ...
stream := TFileStream.Create;
try
stream.WriteBuffer (tab, SizeOf (tab));
// ...
finally
FreeAndNil (stream);
end;
// ...

Pytanie: Ile bajtów zostało zapisanych w strumieniu?
Trochę to dziwne, że Delphi raz traktuje tablice dynamiczne jak zwykłe tablice, a innym razem...
Czy warto stosować tablice dynamiczne, czy lepiej unikać?
Tomasz Kaczanowski

Tomasz Kaczanowski Ot, programista

Temat: Tablice dynamiczne w Turbo Delphi

Wojciech Błoński:
Weźmy taki fragment kodu:

powinno byc:

stream.WriteBuffer (tab[0], 100);

Pytanie: Ile bajtów zostało zapisanych w strumieniu?

zaleznie od wielkości wskaznika w systemie - zgaduje 4
Trochę to dziwne, że Delphi raz traktuje tablice dynamiczne jak zwykłe tablice, a innym razem...

to są wskaźniki z wygodniejszą obsługą...
Czy warto stosować tablice dynamiczne, czy lepiej unikać?

czy należy używac młotka, czy nie - tak samo dobre pytanie - kwestia do czego

konto usunięte

Temat: Tablice dynamiczne w Turbo Delphi

Dziękuję. Bardzo interesujące.
Tak tylko sobie myślę, że filozofia Delphi coraz bardziej upodabnia się do C.
A wszystko zaczęło się od tego:

var
P: Pointer;
A: array of Byte;
begin
//...
P := Addr (A);

Rozumiem, że trzeba tak:

P := Addr (A [0]);
Tomasz Kaczanowski

Tomasz Kaczanowski Ot, programista

Temat: Tablice dynamiczne w Turbo Delphi

Wojciech Błoński:
Dziękuję. Bardzo interesujące.
Tak tylko sobie myślę, że filozofia Delphi coraz bardziej upodabnia się do C.

W zasadzie od dawna C, C++, Pascale traktuje sie jak przenośne asemblery :)
Rozumiem, że trzeba tak:
P := Addr (A [0]);

Tak

konto usunięte

Temat: Tablice dynamiczne w Turbo Delphi

Tablice dynamiczne warto stosować tam gdzie nie możemy z góry określić ile będzie elementów w tej tablicy i jest to celowe w tym przypadku. Stosuje się je np. w definicjach niektórych funkcji przeznaczonych do operacji na tablicach których rozmiar może być różny.

Jeżeli nie wiemy ile elementów ma mieć tablica i zadeklarujemy dużą liczbe elementów np. 10000, to taka tablica zajmuje niepotrzebnie dużo miejsca w pamięci w przypadku gdy wykorzystane są np. tylko 4 pierwsze elementy tablicy.

Przykład 1

type
Pinteger = ^integer;

var
n: integer;
A: Pinteger; // równoważne A: array[0..dowolna_liczba] of integer;
i: integer;
begin
n:=100; //ustalamy wielkość tablicy na 100 elementów
GetMem(A,n*sizeof(integer));
for i:=0 to n-1 do
begin
A[i]:=i;
Writeln('Element tablicy: ',i,'=',A[i]);
end;
FreMem(A,n*sizeof(integer));
end.

Przykład 2

var
A: array[0..1000] of integer;
i: integer;
begin
for i:=0 to 50 do
begin
A[i]:=i;
Writeln('Element tablicy: ',i,'=',A[i]);
end;
end.

W przykładzie 1 ilość elementów tablicy możemy ustalić dowolnie.
W przykładzie 2 ilość elementów tablicy jest ustalona ale duża liczba elementów nie jest wykorzystana. Wiec przykład 1 jest stosowany w przypadkach gdy nie możemy ustalić ile elementów będzie miała tablica ale może powodować błędy w programie. Już to testowałem. Przedstawione powyżej przykłady działają w Lazarus / Free Pascal, w Delphi mogą być problemy.Dariusz Rorat edytował(a) ten post dnia 09.11.09 o godzinie 21:50

konto usunięte

Temat: Tablice dynamiczne w Turbo Delphi

Dariusz Rorat:
Tablice dynamiczne warto stosować tam gdzie nie możemy z góry określić ile będzie elementów w tej tablicy i jest to celowe w tym przypadku. Stosuje się je np. w definicjach niektórych funkcji przeznaczonych do operacji na tablicach których rozmiar może być różny.

Jeżeli nie wiemy ile elementów ma mieć tablica i zadeklarujemy dużą liczbe elementów np. 10000, to taka tablica zajmuje niepotrzebnie dużo miejsca w pamięci w przypadku gdy wykorzystane są np. tylko 4 pierwsze elementy tablicy.

Przykład 1

type
Pinteger = ^integer;

var
n: integer;
A: Pinteger; // równoważne A: array[0..dowolna_liczba] of integer;
i: integer;
begin
n:=100; //ustalamy wielkość tablicy na 100 elementów
GetMem(A,n*sizeof(integer));
for i:=0 to n-1 do
begin
A[i]:=i;
Writeln('Element tablicy: ',i,'=',A[i]);
end;
FreMem(A,n*sizeof(integer));
end.

IMHO GetMem / FreeMem do tablic dynamicznych nie jest najlepszym rozwiązaniem. Lepiej wykorzystać mechanizmy Delphi (A: array of Integer; + SetLength), a najlepiej korzystać z TList i pochodnych.

konto usunięte

Temat: Tablice dynamiczne w Turbo Delphi

Kacper K.:
IMHO GetMem / FreeMem do tablic dynamicznych nie jest najlepszym rozwiązaniem. Lepiej wykorzystać mechanizmy Delphi (A: array of Integer; + SetLength), a najlepiej korzystać z TList i pochodnych.

Z tym, że TList zajmie (chyba) dużo więcej pamięci (jakieś 4 bajty więcej na element).

Osobiście jednak nie polecam tablic dynamicznych.
Potrafią robić psikusy - tak jak stringi w C są nieobliczalne.
Problemy zaczynają się przy kopiowaniu tych struktur:
http://en.allexperts.com/q/Delphi-1595/dynamic-array-c...

Ew. można je opakować w klasę dla bezpieczeństwa.

konto usunięte

Temat: Tablice dynamiczne w Turbo Delphi

Kacper K.:

IMHO GetMem / FreeMem do tablic dynamicznych nie jest najlepszym rozwiązaniem. Lepiej wykorzystać mechanizmy Delphi (A: array of Integer; + SetLength), a najlepiej korzystać z TList i pochodnych.

Polecam rozwiązanie przy użyciu SetLength. Rozmiar tablicy zwiększamy dynamicznie wtedy kiedy trzeba i dokładnie o tyle ile trzeba. Osobiście używam z powodzeniem.

konto usunięte

Temat: Tablice dynamiczne w Turbo Delphi

Rzeczywiście SetLength jest lepsze niż GetMem / Free Mem. Z tymi dwoma przykładami które prezentowałem wcześniej byłyby pewnie problemy w Delphi (w Lazarusie te przykłady działają). Lepiej użyć A: array of integer i użyć SetLength niż A: PInteger i używać GetMem / FreeMem. Dziękuję za cenne wskazówki.

Następna dyskusja:

Turbo Delphi Explorer




Wyślij zaproszenie do