Dynamic controls gives Segmentation fault (11)

  

I’m working on a multiplatform project where I have to create lots of controls dynamically as a result of some major calculations. When changing the conditions, I need to remove all dynamically created controls and make the recalculations and finally create the controls again.

I handle this by first dynamically create a TScrollBox (iOFPLayout) on top of a TTabItem. I move the predefined header TToolBar from the TTabItem to the TScrollBox by changing its parent. Then I create arrays of TLabel, TEdit and TButton controls on the TScrollBox. (I need to interact with the dynamically created controls in code) This part works fine on all platforms. When I remove the controls I use the code below.

On Windows x86, x64 and OS X it seems to work fine. On Android it works fine the first time the TScrollBox is created and filled with dynamically created controls. After the TScrollBox has been removed and recreated I get an “Access Violation” or “Segmentation fault (11)” error at some random point when the dynamic arrays of TLabel controls are created on top of the TScrollBox.

I get a feeling that this has to do with ARC. I have read everything I can about ARC and tested every suggestion I can find but nothing seem to work. Does anyone see what’s wrong?

procedure TTabbedForm.RemoveOFP();
begin
// Move the ToolBar2 back to TabItem3 so it won’t get destroyed
ToolBar2.Parent := TabItem3;
if Assigned(iOFPLayout) then
begin
// iOFPLayout holds a lot of dynamically created controls
iOFPLayout.Release;
iOFPLayout.DisposeOf;
iOFPLayout := nil;
Application.ProcessMessages;
end;
end;

Here is a complete minimal working example.

unit Unit1;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Controls.Presentation, FMX.Layouts;

type
TMainForm = class(TForm)
ToolBar1: TToolBar;
Create: TButton;
Destroy: TButton;
procedure CreateClick(Sender: TObject);
procedure DestroyClick(Sender: TObject);
private
sb: TScrollBox;
lbl: array of TLabel;
end;

var
MainForm: TMainForm;

implementation

{$R *.fmx}

procedure TMainForm.CreateClick(Sender: TObject);
var
i: Integer;
begin
// Create a TScollBox on the MainForm
sb := TScrollBox.Create(Self);
sb.Align := TAlignLayout.Client;
sb.ShowScrollBars := True;
sb.Parent := MainForm;
// Set up the number of labels to put on sb
SetLength(lbl, 1000);
// Create these labels and set some properties
for i := Low(lbl) to High(lbl) do
begin
// On first run on Android devices this causes no problems.
// After DestroyClick has been run after the first CreateClick then
// I get “Access violation / Segmentation fault (11) here.
// It happens after about 800+ labels has been created.
lbl[i] := TLabel.Create(sb);
lbl[i].Text := ‘Label ‘ + IntToStr(i);
lbl[i].Position.X := 10;
lbl[i].Position.Y := i * 20;
lbl[i].Parent := sb;
end;
end;

procedure TMainForm.DestroyClick(Sender: TObject);
begin
if Assigned(sb) then
begin
sb.Release;
sb.DisposeOf;
sb := nil;
end;
end;
end.

Comments are closed.