Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Stackoverflow bei Übergabe von Parametern (Record) an ein Thread (https://www.delphipraxis.net/189920-stackoverflow-bei-uebergabe-von-parametern-record-ein-thread.html)

Alex_ITA01 8. Aug 2016 12:31


Stackoverflow bei Übergabe von Parametern (Record) an ein Thread
 
Hallo,
ich habe folgendes Problem.
Ein Packed Record mit der Gesamtbytegröße von 1620000 Bytes.
Dieses will ich an ein Threadobjekt übergeben für die weitere Bearbeitung oder wofür auch immer.
Ein QT-Beispiel habe ich auch.

Sobald ich die Daten übergeben, kommt eine StackOverflow Exception.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

const
  maxSatz = 200;

type
  TMyRecord2 = packed record
  private
  public
    MyArray2 : array[1..100] of String[80];
  end;

  PMyRecord = ^TMyRecord;
  TMyRecord = packed record
  private
  public
    MyArray : array[1..maxSatz] of TMyRecord2;

    procedure Clear;
  end;

  TMyClass = class(TObject)
  public
    procedure TestFct(aParam : TMyRecord);
  end;

  TMyTask = class(TThread)
  private
    tmpMyClass: TMyClass;
    LokalRec: TMyRecord;
  protected
    procedure Execute; override;
  public
    Constructor Create (CreateSuspended : Boolean);
    destructor Destroy; override;

    procedure SetDaten(aParam: TMyRecord);
  end;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    tmpTask : TMyTask;
    tmpRec: TMyRecord;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
//------------------------------------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
//var
//  tmpValue: Integer;
begin
//  tmpValue := SizeOf(TMyRecord);
//  ShowMessage(tmpValue.ToString + ' Bytes');

  tmpRec.Clear;

  tmpTask := TMyTask.Create(True);
  tmpTask.SetDaten(tmpRec);
  tmpTask.Start;
end;
//------------------------------------------------------------------------------
procedure TForm1.FormDestroy(Sender: TObject);
begin
  if Assigned(tmpTask) then
    FreeAndNil(tmpTask);
end;
//------------------------------------------------------------------------------
{ TMyTask }
//------------------------------------------------------------------------------
constructor TMyTask.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);

  tmpMyClass := TMyClass.Create;
  LokalRec.Clear;
end;
//------------------------------------------------------------------------------
destructor TMyTask.Destroy;
begin
  if Assigned(tmpMyClass) then
    FreeAndNil(tmpMyClass);

  inherited;
end;
//------------------------------------------------------------------------------
procedure TMyTask.Execute;
begin
  FreeOnTerminate := False;

  if Assigned(tmpMyClass) then
    tmpMyClass.TestFct(LokalRec);
end;
//------------------------------------------------------------------------------
procedure TMyTask.SetDaten(aParam: TMyRecord);
begin
  LokalRec := aParam;
end;
//------------------------------------------------------------------------------
{ TMyClass }
//------------------------------------------------------------------------------
procedure TMyClass.TestFct(aParam: TMyRecord);
begin

end;
//------------------------------------------------------------------------------
{ TMyRecord }
//------------------------------------------------------------------------------
procedure TMyRecord.Clear;
begin
  FillChar(Self, SizeOf(Self), 0);
end;
//------------------------------------------------------------------------------
end.
Fehler entsteht hier mit besagter Meldung:
Delphi-Quellcode:
procedure TMyTask.SetDaten(aParam: TMyRecord);
Werden die Daten die übergeben werden, auf dem Stack abgelegt?
Wie würde eure Lösung für sowas aussehen?

Grüße

Wenn ich die Konstante maxSatz von 200 verringere, dann klappt es ab einem bestimmten Wert.

Neutral General 8. Aug 2016 12:39

AW: Stackoverflow bei Übergabe von Parametern (Record) an ein Thread
 
Das hat nichts mit dem Thread zu tun, sondern dass dein Record allein größer als der gesamte Stack ist.
Du solltest dir vllt. überlegen ob du so eine große Menge Daten wirklich brauchst oder du legst die Daten auf dem Heap ab und übergibst nur Pointer.

p80286 8. Aug 2016 12:39

AW: Stackoverflow bei Übergabe von Parametern (Record) an ein Thread
 
Versuch es doch mal so:
Delphi-Quellcode:
procedure TMyTask.SetDaten(const aParam: TMyRecord);
Nach meinem löchrigen Wissen, wird dann der Stack nicht mit einer unnötigen Kopie der Daten belastet.

Gruß
K-H

Alex_ITA01 8. Aug 2016 12:43

AW: Stackoverflow bei Übergabe von Parametern (Record) an ein Thread
 
Stimmt, const funktioniert und da ich die Daten darin nicht ändere, reicht mir das so auch.

Grüße

Zacherl 8. Aug 2016 16:15

AW: Stackoverflow bei Übergabe von Parametern (Record) an ein Thread
 
Zitat:

Zitat von Alex_ITA01 (Beitrag 1344373)
Stimmt, const funktioniert und da ich die Daten darin nicht ändere, reicht mir das so auch.

Und falls doch, nimm einfach einen Pointer auf das entsprechende Struct. Eventuell funktioniert es sogar mit var statt const.

p80286 8. Aug 2016 17:42

AW: Stackoverflow bei Übergabe von Parametern (Record) an ein Thread
 
Zitat:

Zitat von Zacherl (Beitrag 1344395)
Zitat:

Zitat von Alex_ITA01 (Beitrag 1344373)
Stimmt, const funktioniert und da ich die Daten darin nicht ändere, reicht mir das so auch.

Und falls doch, nimm einfach einen Pointer auf das entsprechende Struct. Eventuell funktioniert es sogar mit var statt const.

Soweit ich weiß sind var und const nur Mäntelchen um Pointer vor den Augen des Programmierers zu verbergen, mit Schreibschutz ein/aus.
Bliebe die Frage wo sich diese Riesenstruktur nun befindet.

Gruß
K-H

Zacherl 8. Aug 2016 20:00

AW: Stackoverflow bei Übergabe von Parametern (Record) an ein Thread
 
Zitat:

Zitat von p80286 (Beitrag 1344404)
Soweit ich weiß sind var und const nur Mäntelchen um Pointer vor den Augen des Programmierers zu verbergen, mit Schreibschutz ein/aus.
Bliebe die Frage wo sich diese Riesenstruktur nun befindet.

Genau. Demnach sollte ein var also ebenso gut funktionieren, wie ein const. Wenn die Struktur auf dem Heap liegt, juckt das ja niemanden. Hauptsache nicht auf dem Stack.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:26 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