Kopiowanie tablic dynamicznych

0

Chcę raz na zawsze być pewny.

Mamy taką sytuację:

setLength(DynArray1, x);

for i:=low(DynArray1) to high(DynArray1) do DynArray[i]:=[i];

I teraz chcemy, aby zawartość DynArray1 była w drugiej tablicy. Rozwiązania są 3.

  1. Iteracja i przepisanie każdej wartości
  2. DynArray2:=DynArray1;
  3. copyMemory(dynArray2, dynArray1, sizeof(TypTablicy)*length(dynArray1));

Weźmy przypadek pierwszy. Na początku robimy setLength na dynArray2, potem przepisujemy wszystkie wartości w pętli. Proste i zawsze działa.

Ad 2. Skoro tablica dynamiczna to tak naprawdę wskaźnik, oznacza to, że tablica dynArray2 zaczyna wskazywać na miejsce dynArray1. A jeśli teraz dynArray1 jest składnikiem jakiejś klasy(a dynArray2 nie), to po zniszczeniu tej klasy powinienem dostać w najlepszym wypadku AV po odwołaniu w stylu: dynArray2[i], tak? (w najgorszym zupełnie inne dane)

Ad 3. Załóżmy, że przydzielam pamięć jednorazowo do tablicy, tzn. robię:

setLength(dynArray1, x);

a nie:

for i:=0 to x-1 do
begin
  setLength(dynArray1, 1);
  //jakieś inne operacje
end;

Analogicznie przydzielam pamięć do dynArray2.
W tym wypadku copyMemory powinno zawsze poprawnie zadziałać, tak?
Ale jeśli przydzielałbym pamięć stopniowo(setLength w pętli), to wtedy jest możliwość, że mógłbym w dynArray2 dostać inne dane lub AV, tak?

Czy mój tok rozumowania jest poprawny?

0

1.Wolne ale działa.
2.Nie na wskaźnikach, słyszałeś o przeciążaniu operatorów? To jest właśnie takie coś. poza tym, tablica dynamiczna mi bardziej wygląda na klasę lub obiekt... W końcu one też idą przez referencję (klasa przynajmniej).
3.Niebezpieczne. Nie ważne jak przydzielasz pamięć, to kompilator zawsze doprowadzi do tego że całość będzie w jednym bloku.

Tak przynajmniej wynika z mojej wiedzy...

EDIT:

setLength(dynArray1, 1);

no chyba
setlength(dynarray1,length(dynarray1)+1);

A tak w ogóle to mi się wydaje że za bardzo kombinujesz :P . Nie musisz znać aż tak bardzo wewnętrznej struktury kompilatora...

0
  1. tak
  2. tak
  3. cała tablica jest zawsze ciągła w pamięci więc kopiowanie przez CopyMemory jest bezpieczne
payl napisał(a)

2.Nie na wskaźnikach, słyszałeś o przeciążaniu operatorów? To jest właśnie takie coś. poza tym, tablica dynamiczna mi bardziej wygląda na klasę lub obiekt... W końcu one też idą przez referencję (klasa przynajmniej).

tablica to tablica! Nie żaden obiekt! I tak, zmienna wskazująca na tablicę dynamiczną (czy na obiekt) jest wskaźnikiem, tylko że nie trzeba używać daszka przy odwołaniu
nie uważasz, że

3.Niebezpieczne.
i
Nie ważne jak przydzielasz pamięć, to kompilator zawsze doprowadzi do tego że całość będzie w jednym bloku.
się wzajemnie wykluczają w kontekście pytania Juhasa

0

się wzajemnie wykluczają w kontekście pytania Juhasa

Copymemory bezpieczne? >.> W mojej filozofii: Nie =]

tablica to tablica! Nie żaden obiekt! I tak, zmienna wskazująca na tablicę dynamiczną (czy na obiekt) jest wskaźnikiem, tylko że nie trzeba używać daszka przy odwołaniu

A jednak masz rację... :o

program test;
{$mode objfpc}
uses CRT;
var
  a,b:array of word;
  p:^word;
BEGIN
  setlength(a,5);
  a[0]:=2;
  p:=@a[0];
  b:=a;
  p^:=3;
  writeln(b[0]);
  readln;
END.

Produkuje 3.

Ale...

program test;
{$mode objfpc}
uses CRT;
var
  a,b:array of word;
  p:^word;
BEGIN
  setlength(a,5);
  a[0]:=2;
  p:=@a[0];
  b:=a;
  //p^:=3;
  setlength(b,4);
  a[0]:=3;
  writeln(b[0]);
  writeln(length(a));
  readln;
END.

produkuje 2 i 5. Czyli czyżby to nie był pointer? I skąd kompilator wie kiedy nie używam tablicy i ją wywala? :P

EDIT: Dobra tutaj poczytałem co i jak: http://wiki.freepascal.org/DYNAMIC_ARRAY

1 użytkowników online, w tym zalogowanych: 0, gości: 1