AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Größenveränderung bei dyn. Arrays auf Pointerbasis
Thema durchsuchen
Ansicht
Themen-Optionen

Größenveränderung bei dyn. Arrays auf Pointerbasis

Ein Thema von MStoll · begonnen am 3. Sep 2006 · letzter Beitrag vom 4. Sep 2006
Antwort Antwort
MStoll

Registriert seit: 15. Nov 2005
131 Beiträge
 
Turbo Delphi für Win32
 
#1

Größenveränderung bei dyn. Arrays auf Pointerbasis

  Alt 3. Sep 2006, 23:45
Hallo

derzeit bin ich dabei, Array-Operationen (Sortieren, Austauschen, Vergleichen, Löschen, Einfügen) zu verallgemeinern, indem ich Prozeduren schreiben, denen ich ein dyn. Array als Zeiger übergebe (Siehe auch bei den Vorschlägen zur Code-Library, Thread "Shellsort für beliebige Arrays"). Sortieren, Austauschen und Vergleichen (bei statischen Typen!) geht soweit ganz gut allgemein, da sie keine Größenveränderungen am Array verursachen. Hab auch schon ne Basis für eine Lösch-Prozedur. Allerdings will es mir nicht gelingen, dabei die Größe des Arrays innerhalb der Prozedur zu verändern. Deshalb muss ich das immer so aufrufen:
Delphi-Quellcode:
ArrDelete(Arr, Length(Arr), SizeOf(Arr), idx);
SetLength(Arr, Length(Arr)-1);
Die ArrDelete-Prozedur sieht so aus:
Delphi-Quellcode:
procedure Exch(P : Pointer; ElSize : integer; a, b : integer);
var P1, P2 : Pointer;
    B1 : byte;
    x : integer;
begin
     P1 := Pointer(Integer(P) + ElSize * a);
     P2 := Pointer(Integer(P) + ElSize * b);
     
     for x := 0 to ElSize-1 do
     begin
          b1 := Byte(Pointer(Integer(P1)+x)^);
          Byte(Pointer(Integer(P1)+x)^) := Byte(Pointer(Integer(P2)+x)^);
          Byte(Pointer(Integer(P2)+x)^) := b1;
     end;
end;

procedure ArrDelete(P : Pointer; Size, ElSize, Idx : integer);
var x : integer;
begin
     if (Idx < 0) or (Idx >= Size) then
        exit;

     for x := Idx to Size-2 do
         Exch(P, ElSize, x, x+1);
end;
Ich würde nun gern letzteres SetLength irgendwie in die ArrDelete-Prozedur mit reintun.

Hat jemand eine Idee?

Danke
Michael
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Größenveränderung bei dyn. Arrays auf Pointerbasis

  Alt 4. Sep 2006, 08:18
Verwende lieber var-Paramter statt den pointern, dann solte es funktionieren.
BTW. Dynamische Array sind eigentlich schon Pointer.
Markus Kinzler
  Mit Zitat antworten Zitat
MStoll

Registriert seit: 15. Nov 2005
131 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Größenveränderung bei dyn. Arrays auf Pointerbasis

  Alt 4. Sep 2006, 09:02
und welchen Typ soll dieser var-Parameter haben? Ich habe genau deshalb Pointer gewählt, um JEDEN Array-Typ verarbeiten zu können. Wie das speziell für die einzelnen Array-Typen geht, weiß ich ja...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.033 Beiträge
 
Delphi 12 Athens
 
#4

Re: Größenveränderung bei dyn. Arrays auf Pointerbasis

  Alt 4. Sep 2006, 12:28
Etwa so?
Delphi-Quellcode:
Type TIntegerArray = Array of Integer;
  PIntegerArray = ^TIntegerArray;

SetLength(TIntegerArray(P), 123);
// oder
SetLength(PIntegerArray(P)^, 123);


//zusammen mit Length dann so
//(wobei man in der Längenangabe auch einen Standardarraytyp
//verwenden kann, da die Längengabe nicht vom Arraytyp abhängig ist)
SetLength(TIntegerArray(P), Length(TIntegerArray(P)) - 1);
SetLength(TIntegerArray(P), High(TIntegerArray(P)));
SetLength(TIntegerArray(P), (PInteger(P) - 4)^ - 1);
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
MStoll

Registriert seit: 15. Nov 2005
131 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Größenveränderung bei dyn. Arrays auf Pointerbasis

  Alt 4. Sep 2006, 20:25
Das funktioniert leider nicht, da gibt's den Fehler "Ungültige Zeigeroperation". Wenn ich z.B. ein array of extended als TByteArr caste und dann in dieser Prozedur mit SetLength die Größe ändere, wird außerdem alles genullt, was hinter der Grenze zur ursprünglichen Länge liegt. Schwer zu erklären, daher ein Beispiel:

Delphi-Quellcode:
type TByteArr = array of byte;
procedure ArrDelete(var P : TByteArr; Size, ElSize, Idx : integer);
begin
     // ...
     SetLength(P, Length(P)-1); // So werden nur 19 statt der für extended-arr nötigen 190 Bytes reserviert
     SetLength(P, (length(P)-1) * ElSize); // So werden zwar 190 Bytes reserviert, allerdings ist Length(P) dann zu groß
                                            // außerdem wird alles nach Byte Nr. 20 gelöscht
end;

procedure test;
var a : array of extended;
begin
     SetLength(a, 20);
     ArrDelete(TByteArr(a), Length(a), SizeOf(a[0]), 2);

     // dann "Ungültige Zeigeroperation
     // ...
end;
Hast du das schonmal ausprobiert, was du sagst? Wenn ja, könntest du bitte ein compilier- und lauffähiges Stück Code posten?
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:09 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz