Recent

Author Topic: Creating "TEdit" component dynamically  (Read 3093 times)

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Creating "TEdit" component dynamically
« Reply #15 on: May 06, 2021, 06:15:00 am »
On the other hand, giving a non-nil owner to a component on its constructor means that we're transferring the life-cycle management to that owner.

Not always. For example imagine, if you will, you're creating a series of anonimous temporary controls and, for whatever reason, you don't want to create the tipical list to contain them. Giving them an Owner means that they will be locatable through the owner's Components "array" without necessarily meaning you want that owner to be responsible for them.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

alpine

  • Hero Member
  • *****
  • Posts: 1037
Re: Creating "TEdit" component dynamically
« Reply #16 on: May 06, 2021, 01:04:31 pm »
Formally true. My wording must be read "You may not free it" instead of "You shall not free it" then.

I have already admitted my incorrect statement. In practice, there can be many different cases that an experienced programmer knows how to handle. Generally, the life cycle management is something that must be taken most responsibly. I'm still thinking that mixing approaches is the sloped road to UAF. After all, even experienced programmers are not immune to it.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Creating "TEdit" component dynamically
« Reply #17 on: May 06, 2021, 03:37:08 pm »
As lucamar said, the:
Code: Pascal  [Select][+][-]
  1.   e1.Create(Self);
  2.  
means "call the method Create on instance of TEdit named e1", but e1 doesn't exist yet and also does not have such a method.

To be fair it's perfectly fine to call a constructor as a normal method. The creation “magic” only exists when called using a class type.

This also means if you have a constructor that doesn't access any of the fields, then that will work without problems on an invalid instance (as with any method) and the problems will only occur later, because the instance wasn't created (been there, done that :P ).

alpine

  • Hero Member
  • *****
  • Posts: 1037
Re: Creating "TEdit" component dynamically
« Reply #18 on: May 06, 2021, 05:15:23 pm »
To be honest, I suspected something like that (but how else to present this to a rookie). I'm curious about the realization, because, unlike C++, here the instances are purely dynamic and must be created explicitly. From what you say, I conclude that "magic" is the allocation on the heap and it only happens if it is called through the class. Otherwise, the constructor is called with an invalid Self as a regular method, is that correct? Isn't it forbidden from the compiler? I have never tried it...
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Creating "TEdit" component dynamically
« Reply #19 on: May 06, 2021, 06:54:46 pm »
Otherwise, the constructor is called with an invalid Self as a regular method, is that correct? Isn't it forbidden from the compiler? I have never tried it...

Yes, if the object hasn't been created normally then it's called with an invalid Self. It's not forbidden because there might be legitimate reasons to call it through an instance as a normal method (e.g. to "reset" the object to its default state).

(been there, done that :P ).

As, I guess, most of us when coding in a hurry and not thinking clearly: "Oh, I forgot to create that string list! Let's see: MyStrings.Create; ..." :-[ :D
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

alpine

  • Hero Member
  • *****
  • Posts: 1037
Re: Creating "TEdit" component dynamically
« Reply #20 on: May 06, 2021, 07:53:44 pm »
*snip*
Yes, if the object hasn't been created normally then it's called with an invalid Self. It's not forbidden because there might be legitimate reasons to call it through an instance as a normal method (e.g. to "reset" the object to its default state).
*snip*

After reading few articles now I see it clearly! We use it all the time in the constructors (inherited Create;).

Makes me think that the usual heap allocation can be skipped (e.g. for tiny embedded) and have a 'static' instances, something like:

Code: Pascal  [Select][+][-]
  1. var
  2.   Buf: array [0..MaxBuf-1] of Byte;
  3.   Mark: Integer;
  4.   O1, O2: TMyObject;
  5. begin
  6.    Mark := 0;
  7.    O1 := TMyObject(@Buf[Mark]); Mark := Mark + TMyObject.InstanceSize;
  8.    O1.Create;
  9.    O2 := TMyObject(@Buf[Mark]); Mark := Mark + TMyObject.InstanceSize;
  10.    O2.Create;
  11.    // etc.
  12.    MainProc;
  13. end.
  14.  

Of course that kind of objects should never be Free'd.

BTW, using obj.Create for resetting is considered a very dangerous practice.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Creating "TEdit" component dynamically
« Reply #21 on: May 06, 2021, 08:00:04 pm »
BTW, using obj.Create for resetting is considered a very dangerous practice.

Thence my previous advice :D
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

alpine

  • Hero Member
  • *****
  • Posts: 1037
Re: Creating "TEdit" component dynamically
« Reply #22 on: May 06, 2021, 08:08:14 pm »
Thence my previous advice :D
Absolutely right! Sorry, little dizzy of my (personal) findings.

BTW, Is there a way to know InstanceSize at compile time? Something like SizeOf()? 
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Creating "TEdit" component dynamically
« Reply #23 on: May 06, 2021, 09:13:44 pm »
BTW, Is there a way to know InstanceSize at compile time? Something like SizeOf()?

Not that I know of, sorry.

If I may ask, why do you want it? For most classes InstanceSize is only a "lower estimation".
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

alpine

  • Hero Member
  • *****
  • Posts: 1037
Re: Creating "TEdit" component dynamically
« Reply #24 on: May 06, 2021, 09:36:15 pm »

Not that I know of, sorry.

If I may ask, why do you want it? For most classes InstanceSize is only a "lower estimation".

For specifying the upper bound of the pre-allocated buffer in
https://forum.lazarus.freepascal.org/index.php/topic,54470.msg404786.html#msg404786
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

 

TinyPortal © 2005-2018