Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2012-08

Pointer woes when trying to port a Delphi program

4 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

brian

Hi all,

I'm trying to port a Delphi program to Lazarus, although I'm redoing the interface from scratch.

Without getting into to much detail about what the program does, it needs an array of 72 buttons on the main screen, these buttons have their captions changed and are variously enabled and disabled as the program executes.

Because of the underlying logic, it's easiest to manipulate these buttons as an array of pointers to the buttons (in fact two arrays, but that's not really relevant).

So, I have

Type
  TBtnPtr = ^TButton;
  TBtnArray = Array [1..36] of TBtnPtr;
Var
  Buttons1, Buttons2 : TBtnArray;

Then in a procedure called from the Form's OnCreate, I set the arrays up :-

Buttons[1]^ := FirstButton;
Buttons[2]^ := SecondButton;

etc, etc.

Everything compiles OK, but at runtime, the moment the program reaches that first assignment statement running interactively under GDB, I get an error "Exception class External : SIGSEGV"

This is using SVN 38353M (downloaded and built this morning) with FPC 2.6.0 on an AMD Phenom X4 box running Debian SID 64-bit, and generating a 64 bit executable.

I'm lost. This same code worked under Delphi 7. Can anyone give me a hint as to what I'm doing wrong? I wanted to create the buttons as design time so that I can set the initial layout, but if I need to create them dynamically I can do that.

Thanks

Brian

Reply by email

ik
to brian
brian wrote 45 lines
Hi all, I'm trying to port a Delphi program to Lazarus, although I'm redoing the interface from scratch. Without getting into to much detail about what the program does, it needs an array of 72 buttons on the main screen, these buttons have their captions changed and are variously enabled and disabled as the program executes. Because of the underlying logic, it's easiest to manipulate these buttons as an array of pointers to the buttons (in fact two arrays, but that's not really relevant). So, I have Type TBtnPtr = ^TButton; TBtnArray = Array [1..36] of TBtnPtr; Var Buttons1, Buttons2 : TBtnArray; Then in a procedure called from the Form's OnCreate, I set the arrays up :- Buttons[1]^ := FirstButton; Buttons[2]^ := SecondButton; etc, etc. Everything compiles OK, but at runtime, the moment the program reaches that first assignment statement running interactively under GDB, I get an error "Exception class External : SIGSEGV" This is using SVN 38353M (downloaded and built this morning) with FPC 2.6.0 on an AMD Phenom X4 box running Debian SID 64-bit, and generating a 64 bit executable. I'm lost. This same code worked under Delphi 7. Can anyone give me a hint as to what I'm doing wrong? I wanted to create the buttons as design time so that I can set the initial layout, but if I need to create them dynamically I can do that.

It will not answer your question (there are few details that are missing there), but I'ved wrote a component for Lazarus few years ago that provide a grid of buttons:
https://github.com/ik5/linesip-components

It might be useful for your to try and use it instead, or at least learn from it.

Show quoted text 5 lines
Thanks Brian

Ido

Show quoted text 7 lines
-- ______________________________**_________________ Lazarus mailing list .**freepascal.org http://lists.lazarus.**freepascal.org/mailman/**listinfo/lazarus<http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20120824/fd2b5371/attachment-0001.html>

Reply by email

Juha Manninen
to brian: I'm trying to port a Delphi program to Lazarus, although I'm redoing the interface from…
brian wrote
Type TBtnPtr = ^TButton; TBtnArray = Array [1..36] of TBtnPtr;

TButton is a reference type. Reference is basically a pointer which does not require the pointer syntax.
You are really defining a pointer to pointer, a useless indirection there. It makes things more difficult and you make errors more easily and may even get a SIGSEGV :)

Do this instead:

type
TBtnArray = Array [1..36] of TButton;

Juha
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20120824/1353d690/attachment.html>

Reply by email

Bernd
to brian: I'm trying to port a Delphi program to Lazarus, although I'm redoing the interface from…

2012/8/24 brian :

Buttons[1]^ := FirstButton;

It is crashing because here you are dereferencing an uninitialized pointer Button[1] does not contain any reasonable value at this moment, Button[1]^ therefore points to some random location and Buton[1]^:= is trying to write something to that random memory location and will therefore segfault.

But actually what you really want to do in a situation where you initialize an array of pointers would be to write the *address* of something *into* the array:

ArrayOfPointers[1] := @SomeThing;

But this also does not really make much sense in your scenario as others have noted already, the variable FirstButton is of type TButton and because TButton is a class this variable *is* something like a pointer already (its holds a reference of a TButton instance, actually internally it really is just a pointer). So you should just define your array like this:

Type
 TBtnArray = Array [1..36] of TButton;
var
 Buttons: TBtnArray;
begin
  Buttons[1] := FirstButton;

If you look a the generated Assembly code you will see that it really treats these TButton variables like pointers and the array is just an array of Pointers, although you did not need to write any Pointer syntax anywhere at all (most of the time when designing your data structures wisely you don't need to use pointer syntax and even if you are porting or interfacing with C++ code you can often (not always) come up with equivalent Pascal code that greatly reduces the amount of needed Pointer syntax, looking much more elegant and readable).

Reply by email