![]() |
sporadisch auftretende Nil-Pointer
Liste der Anhänge anzeigen (Anzahl: 2)
Ich hab hier eine kleine Plotter-Klasse geschrieben. Diese nimmt zweidimensional Daten entgegen und kann diesesowohl absolut als auch relativ als Säulen- oder Liniendiagramm darstellen. Eine kleine Beispielausgabe hab ich angehängt ;)
In der Zeichenprozedur wirft es nun, nahezu zufällig (in etwa 50% der aufrufe), AVs mit "read from 000000000", beim Zugriff auf ein dynamisches array, dessen grenzen eigentlich absolut sicher sind. Auch kommt zwischen durch immer mal ein Zitat:
Delphi-Quellcode:
function TPlotter.DrawGraph(dimensions:TPoint;scale:single;range:TIntArray):TBitMap32;
var i,k:integer; P:TPoint; mult:single; YOffSet:integer; value:single; begin YOffSet:=3; //init result:=TBitmap32.Create; result.Width := dimensions.X; result.Height := dimensions.Y; if updating or (length(fdata) < 1) then exit; dimensions.X := length(fdata) * length(fdata[1]) * XOffSet; result.Width := dimensions.X; result.Canvas.Brush.Color := clwhite; result.Canvas.Rectangle(0,0,dimensions.X,dimensions.Y); result.Canvas.Pen.Color := clblack; //hier kommt das mit der leinwand. result.Canvas.Brush.Style := bsclear; //param checking range[0]:=Max(low(fData),range[0]); range[1]:=Min(high(fData),range[1]); if fMaxValue <> 0 then mult := (dimensions.Y -10) / (fMaxValue + YOffSet) * scale else mult := 1; //drawing drawscale(mult,-YOffSet,10,result); result.Canvas.Pen.Width:=5; case fstyle of sColumns: for i := range[0] to range[1] do for k:= 0 to length(fData[i])-1 do begin result.Canvas.Pen.Color := fColors[k]; P.X := round((i* result.Width / range[1] - range[0] / 2) + k*4 + 20); value := fdata[i,k]; // manchmal hier.... if (drawmode = dmChanges) then value := fdata[i,k] - fdata[Max(i-1,0),k]; // und manschmal da.... P.Y := round(value*mult) ; result.Canvas.MoveTo(P.X,result.Height - 1 - round(YOffSet * mult)); result.Canvas.LineTo(P.X,result.Height - P.Y -round(YOffSet * mult)-1); end; sLines: for k:= 0 to length(fData[0])-1 do for i := range[0] to range[1] do begin result.Canvas.Pen.Color := fColors[k]; P.X := round((i* result.Width / range[1] - range[0] / 2) + k*4 + 20); value := fdata[i,k]; //hier unten natürlich auch. if (drawmode = dmChanges) then value := fdata[i,k] - fdata[Max(i-1,0),k]; P.Y := round(value*mult) ; if i=0 then result.Canvas.MoveTo(0, result.Height - P.Y -round(YOffSet * mult)-1); result.Canvas.LineTo(P.X,result.Height - P.Y -round(YOffSet * mult)-1); end; end; drawlegend(rect(0,0,100,300),result); end; |
Re: sporadisch auftretende Nil-Pointer
Mal Bereichsprüfung in den Projekt-Optionen aktiviert. Eventuell schreibst du irgendwo über Array-Grenzen hinaus ...
|
Re: sporadisch auftretende Nil-Pointer
ja, das war exakt das problem. allerdings in einer dimension, in die ich nicht gleich geschaut hab ;). habs jetzt rausgekriegt.
So alloziiere ich mein array:
Delphi-Quellcode:
Ich vergrößere mein array also immer um 172% und in der zweiten dimension wird es erst alloziiert, wenn ein wert zugewiesen wird.
procedure TPlotter.AddData(data: array of single);
var i,newlength:integer; max:single; begin //memory management if length(fdata) <= fOccupied then begin newlength:=round(length(fdata)*1.72)+1; setlength(fdata,newlength); end; //value assignment fOccupied:=fOccupied+1; setlength(fData[fOccupied-1],IfThen((fOccupied - 1 = 0),length(data),length(fdata[0]))); for i := 0 to high(fData[fOccupied-1]) do begin fData[fOccupied-1,i]:=data[i]; fMaxValue:=math.max(fMaxValue,data[i]); end; end; und in meiner glorreichen Intelligenz hab ich natürlich beim überprüfen der array-grenzen mist gebaut(ein ausschnitt aus der funktion, die im ersten post gepostet ist):
Delphi-Quellcode:
das high(fData) muss natürlich fOccupied-1 heissen. :roll:
//param checking
range[0]:=Max(low(fData),range[0]); range[1]:=Min(high(fData),range[1]); Vielen Dank für ihre geschätzte Aufmerksamkeit. :zwinker: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz