Kopiowanie tablic dynamicznych

Odpowiedz Nowy wątek
2011-08-19 15:59
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?

edytowany 2x, ostatnio: madmike, 2011-08-20 10:50
TAGUJ wątki nazwą języka/środowiska!!! - madmike 2011-08-20 10:51

Pozostało 580 znaków

2011-08-19 16:49
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...


Nie pisz do mnie PM o czymś co nie dotyczy bezpośrednio mnie. | Nie rozmawiaj ze mną jeśli brak Ci kultury (wystarczy że mi brakuje) | Nie jestem zły, jestem po prostu zły.
edytowany 3x, ostatnio: payl, 2011-08-19 16:55

Pozostało 580 znaków

2011-08-19 18:54
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


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2011-08-19 20:02
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


Nie pisz do mnie PM o czymś co nie dotyczy bezpośrednio mnie. | Nie rozmawiaj ze mną jeśli brak Ci kultury (wystarczy że mi brakuje) | Nie jestem zły, jestem po prostu zły.
edytowany 1x, ostatnio: payl, 2011-08-19 20:16

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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