AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit Pointern

Ein Thema von Sascha · begonnen am 6. Jun 2009 · letzter Beitrag vom 8. Jun 2009
Antwort Antwort
Sascha

Registriert seit: 4. Jul 2003
Ort: Lübeck
58 Beiträge
 
Delphi 2005 Personal
 
#1

Problem mit Pointern

  Alt 6. Jun 2009, 22:07
Delphi-Quellcode:
  PKnoten = ^TKnoten;

  TKnoten = record // Record für Knoten
  public
   pSuper ,pBit0, pBit1: PKnoten;
   bSuper: boolean;
   iHaeufigkeit: int64;
   cBuchstabe: char;
  end;

 ...

var
 aKnoten: array of TKnoten;
Delphi-Quellcode:
 ShowMessage(IntToStr(aKnoten[4].pBit0^.iHaeufigkeit));
 ShowMessage(IntToStr(aKnoten[4].pBit0^.iHaeufigkeit));
Bei der ersten Message kommt 3 raus (was richtig ist), beim zweiten mal jedoch 0.
Die Beiden Zeilen stehen genau hintereinander. Nur wo ist da der Fehler das das passiert?

(Delphi2005)
Gruß Sascha.
Man liest sich
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#2

Re: Problem mit Pointern

  Alt 7. Jun 2009, 00:38
Meine Glaskugel sagt mir, dass du die Zeiger nicht mit New initialisiert hast.

New(aKnoten[4].pBit0);
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#3

Re: Problem mit Pointern

  Alt 7. Jun 2009, 00:41
Mein Verstand sagt mir, dass Dezipaitor .iHaeufigkeit noch entfernen wollte. Mein Verstand war langsamer als seine Finger...

Meine Glaskugel sagt mir, dass du dir u.a. Pointer auf Array Elemente von aKnoten vermerkt, u.a. in anderen Knoten der Liste. Leider aber auch zwischendurch die Liste verlängerst/verkürzt. Dabei wiederrum werden aber u.U. alle Zeiger ungültig in der Liste, da ein dynamisches Array frei im Speicher bewegt wird bei der Realloziierung, abhängig davon wo Speicher zur Verfügung steht.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Problem mit Pointern

  Alt 7. Jun 2009, 00:41
bei 2 mal der exakt gleichen Anweisung hintereinander passieren verschiedene Dinge? Wenn dem so ist so genügt der zusammgengekürzte Quelltext den du uns offenbart hast nicht aus um den Fehler zu finden.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von thkerkmann
thkerkmann

Registriert seit: 7. Jan 2006
Ort: Pulheim Brauweiler
464 Beiträge
 
Delphi 2010 Professional
 
#5

Re: Problem mit Pointern

  Alt 7. Jun 2009, 09:47
Hi,

ich würde es vermeiden, eine Verkettete Listen Struktur in dynamischen Arrays abzulegen. Das widerspricht sich für mich irgendwie. Hier wird mit New() und Dispose() gearbeitet. Wenn Du in dynamischen Arrays arbeiten willst, verwende keine Zeiger, sondern Indices um auf andere Elemente in dem Array zu verweisen. Das gehört wieder zusammen.

Gruss
Thomas Kerkmann
Ich hab noch einen Koffer in Borland.
http://thomaskerkmann.wordpress.com/
  Mit Zitat antworten Zitat
Sascha

Registriert seit: 4. Jul 2003
Ort: Lübeck
58 Beiträge
 
Delphi 2005 Personal
 
#6

Re: Problem mit Pointern

  Alt 7. Jun 2009, 10:33
Delphi-Quellcode:
var
  Form1: TForm1;
  aKnoten: array of TKnoten;

const
  cBuchs: array[0..3] of char = ('c', 'a', 'b', 'd');
  iBuchs: array[0..3] of int64 = (6, 5, 2, 3);

implementation
{$R *.dfm}
{$O-}

procedure TForm1.Button1Click(Sender: TObject);
var
 i, x: int64; // x = Length aKnoten
 Mi0, Mi1: TMinInd;
 Point: PKnoten;
 bitcode: string;
begin
 // anderweitige Initialisierung
 x := length(iBuchs);
 SetLength(aKnoten, x);
 // anderweitige Initialisierung -> Complete

 // Komplettinitialisierung des verwendeten Arrays
 i := 0;
 repeat
  aKnoten[i].cBuchstabe := cbuchs[i];
  aKnoten[i].iHaeufigkeit := ibuchs[i];
  aKnoten[i].pSuper := nil;
  aKnoten[i].pBit0 := nil;
  aKnoten[i].pBit1 := nil;
  inc(i);
 until (i = x);
 // Komplettinitialisierung des verwendeten Arrays -> Complete

 // Damit Schleife nicht gleich abbricht
 // Danach Baumerstellung
 mi1.haeuf := high(int64) - 1;
 while mi1.haeuf <> high(int64) do
 begin
  mi1.index := -1;
  mi1.haeuf := high(int64);
  mi0.index := -1;
  mi0.haeuf := high(int64);
  i := -1;
  repeat
   inc(i);
   if (aKnoten[i].iHaeufigkeit < mi1.haeuf) and
    (aKnoten[i].pSuper = nil) then
   begin
    mi1.index := mi0.index;
    mi1.haeuf := mi0.haeuf;
    mi0.index := i;
    mi0.haeuf := aKnoten[i].iHaeufigkeit;
   end;
  until (i = x - 1);
  Memo1.Lines.Add('indexi: ' + IntToStr(i));
  Memo1.Lines.Add('index0: ' + IntToStr(mi0.index));
  Memo1.Lines.Add('haeuf0: ' + IntToStr(mi0.haeuf));
  Memo1.Lines.Add('index1: ' + IntToStr(mi1.index));
  Memo1.Lines.Add('haeuf1: ' + IntToStr(mi1.haeuf));
  Memo1.Lines.Add('------------');


  // neuen Knoten hinzufügen
  if mi1.index <> -1 then
  begin
   inc(x);
   SetLength(aKnoten, x);
   aKnoten[x - 1].pSuper := nil;
   aKnoten[x - 1].iHaeufigkeit := mi1.haeuf
     + mi0.haeuf;
   aKnoten[x - 1].pBit0 := @aKnoten[mi0.index];
   aKnoten[x - 1].pBit1 := @aKnoten[mi1.index];
   aKnoten[x - 1].cBuchstabe := #0;

   aKnoten[mi0.index].pSuper := @aKnoten[x - 1];
   aKnoten[mi0.index].bSuper := false;
   aKnoten[mi1.index].pSuper := @aKnoten[x - 1];
   aKnoten[mi1.index].bSuper := true;
  end;
  // neuen Knoten hinzufügen -> Complete
 end;

 // BitCode auslesen!
 i := 0;
{
  repeat
  if (aKnoten[i].pBit0 = nil) and (aKnoten[i].pBit1 = nil) then
  begin
  // Hier Code zum BitCode auslesen schreiben!
  bitcode := '';

  if aKnoten[i].bSuper then bitcode := '1' + bitcode
    else bitcode := '0' + bitcode;

  Point := aKnoten[i].pSuper;

  while (Point^.pSuper <> nil) do
  begin
    Point := Point^.pSuper;
    if Point.bSuper then bitcode := '1' + bitcode
    else bitcode := '0' + bitcode;
  end;

  Memo1.Lines.Add('BitCode für *' +
    aKnoten[i].cBuchstabe + '* =' + bitcode);
  end;
  inc(i);
until i = length(aKnoten);
}

 Point := aKnoten[4].pBit0;
 ShowMessage(IntToStr(aKnoten[4].pBit0^.iHaeufigkeit));
 ShowMessage(IntToStr(aKnoten[4].pBit0^.iHaeufigkeit));
{
point := aKnoten[3].pSuper;
while (point^.pSuper <> nil) do
begin
  ShowMessage(IntToStr(point^.iHaeufigkeit));
  point := point^.pSuper;
end;
}


 // BitCode auslesen! -> Complete
end;


end.
Gruß Sascha.
Man liest sich
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Problem mit Pointern

  Alt 7. Jun 2009, 10:58
Muetze1 hat den Fehler richtig vermutet gehabt:
Du holst dir die Adresse eines Arrayelementes und speicherst/merkst dir diese
aKnoten[mi0.index].pSuper := @aKnoten[x - 1]; Wenn du dann allerdings mit
SetLength(aKnoten, x); die Größe des Arrays änderst wird unter umständen das Array wo anders in den Speicher hinkopiert (weil an der aktuellen Position nicht genug Platz ist zum vergrößern).
Somit hast du in .pSuper eine alte Adresse stehen die nicht mehr aktuell ist weil das Array jetzt wo ganz anders im Speicher liegt.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Sascha

Registriert seit: 4. Jul 2003
Ort: Lübeck
58 Beiträge
 
Delphi 2005 Personal
 
#8

Re: Problem mit Pointern

  Alt 7. Jun 2009, 11:37
naja nur beim ersten aufruf kommt das richtige ergebnis.. in der zeile danach nicht..
und unter Delphi 2008 läuft es ohne fehler.
Unter Delphi2005 bekomme ich den Fehler...
Gruß Sascha.
Man liest sich
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#9

Re: Problem mit Pointern

  Alt 8. Jun 2009, 09:31
Zitat von Sascha:
naja nur beim ersten aufruf kommt das richtige ergebnis.. in der zeile danach nicht..
und unter Delphi 2008 läuft es ohne fehler.
Unter Delphi2005 bekomme ich den Fehler...
Wie viel Speicher nach dem Array noch frei ist, um es zu vergrößeren, ist nun mal von vielen Faktoren abhängig.
Nach jeder Vergrößerung können alle Pointer auf Elemente dieses Arrays ungültig werden.
Das ist im Prinzip in jeder Delphiversion so.

Verwende statt dessen ein TList-Object und erstelle die Knoten mit New und gib diese mit Dispose wieder frei.
  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 12:58 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