Board index » delphi » Comon you pro's - Long strings as class members

Comon you pro's - Long strings as class members

Hi there ...

I've got a class derived from TObject, with a member of type long
string(AnsiString).

However, whenever I try to assign a value to the string, my app just stops!

I thought dynamic string allocation was transparent?

Any comment??

Thanx

Erik Marais

 

Re:Comon you pro's - Long strings as class members


Quote
Erik Marais wrote:

> Hi there ...

> I've got a class derived from TObject, with a member of type long
> string(AnsiString).

> However, whenever I try to assign a value to the string, my app just stops!

> I thought dynamic string allocation was transparent?

> Any comment??

        You've got comments from at least two people already - look
and see if there are any replies to your previous post.

        It seems very likely that you're doing something wrong.
Hard to say what without seeing what you're doing. Yesterday I
posted a class just for you that contains a string property -
it works for me with no problem.

--
David Ullrich

sig.txt not found

Re:Comon you pro's - Long strings as class members


On 22 Oct 1997 10:39:52 GMT, "Erik Marais" <Erik.Mar...@sanlam.co.za>
wrote:

Quote
>I've got a class derived from TObject, with a member of type long
>string(AnsiString).

>However, whenever I try to assign a value to the string, my app just stops!

>I thought dynamic string allocation was transparent?

Reduce your program to the smallest possible program that manifests
your problem. Then post exactly that code with no further editing.
Without knowing what your program does, there's nothing we can do to
help you. If the program you post is too long, we won't have time to
read it, and so will not be able to help you.
--
Ray Lischner (http://www.tempest-sw.com/)
Author of "Hidden Paths of Delphi 3: Experts, Wizards, and the Open Tools API"

Re:Comon you pro's - Long strings as class members


Thanks David.

Yes, I found your reply after I've sent the the second post. Kind of new to
this Explorer News thing.

Here is some code that does not work. You might have to construct it
visually yourself. I've put
comments near the parts I've added myself.  {!!!}

This code causes an EAccessViolation even on 95.
It assigns the '' to MyClass.s successfully, but generates the exception
when you close the form.

Under NT, I get a lot more errors, about four EAccessViolation message
boxes through out runtime.

I thought this might be a problem specific to NT, but now I've tried this
at work 95 and it is doing the same.

Appologies for my un-informative messages.

Thank you for your interest. Help will be welcome.

Erik

---------------------------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TMyClass = class(TObject)     {!!!}
  public
    s: string;
    constructor create;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

constructor TMyClass.Create;  {!!!}
begin
     inherited Create;
     s := '';
end;

procedure TForm1.Button1Click(Sender: TObject); {!!!}
var MyClass : TMyClass;
begin
     MyClass.Create;
     MyClass.s := '';
end;

end.

David Ullrich <ullr...@math.okstate.edu> wrote in article
<344E18A7.2...@math.okstate.edu>...

Quote
> Erik Marais wrote:

> > Hi there ...

> > I've got a class derived from TObject, with a member of type long
> > string(AnsiString).

> > However, whenever I try to assign a value to the string, my app just
stops!

> > I thought dynamic string allocation was transparent?

> > Any comment??

>    You've got comments from at least two people already - look
> and see if there are any replies to your previous post.

>    It seems very likely that you're doing something wrong.
> Hard to say what without seeing what you're doing. Yesterday I
> posted a class just for you that contains a string property -
> it works for me with no problem.

> --
> David Ullrich

> sig.txt not found

Re:Comon you pro's - Long strings as class members


On 23 Oct 1997 10:08:05 GMT, "Erik Marais" <Erik.Mar...@sanlam.co.za>
wrote:

Quote
>Here is some code that does not work. You might have to construct it
>visually yourself. I've put
>comments near the parts I've added myself.  {!!!}

The problem isn't to do with strings, it's to do with the way
constructors work in Delphi:

Quote
>procedure TForm1.Button1Click(Sender: TObject); {!!!}
>var MyClass : TMyClass;
>begin
>     MyClass.Create;
>     MyClass.s := '';
>end;

>end.

Constructors are essentially functions, not procedures.  Calling
MyClass.Create creates a new object of the right class, then throws
away the result:  it doesn't assign it to MyClass.  You need

 MyClass := TMyClass.Create;

Duncan Murdoch

Re:Comon you pro's - Long strings as class members


Quote
Erik Marais wrote:

<snip>
Quote
> procedure TForm1.Button1Click(Sender: TObject); {!!!}
> var MyClass : TMyClass;
> begin
>      MyClass.Create;
>      MyClass.s := '';
> end;

<snip>

The first line of the procedure should be
  MyClass := TMyClass.Create;

Chris Jobson

Re:Comon you pro's - Long strings as class members


Quote
Ray Lischner wrote:
> [...]

> Reduce your program to the smallest possible program that manifests
> your problem. Then post exactly that code with no further editing.
> Without knowing what your program does, there's nothing we can do to
> help you. If the program you post is too long, we won't have time to
> read it, and so will not be able to help you.

        Glad to see I'm not the only one who can't find the
snippet that DM posted... I wonder where it came from?

--
David Ullrich

sig.txt not found

Re:Comon you pro's - Long strings as class members


Quote
Duncan Murdoch wrote:

> On 23 Oct 1997 10:08:05 GMT, "Erik Marais" <Erik.Mar...@sanlam.co.za>
> wrote:

> >Here is some code that does not work. You might have to construct it
> >visually yourself. I've put
> >comments near the parts I've added myself.  {!!!}

> The problem isn't to do with strings, it's to do with the way
> constructors work in Delphi:

> >procedure TForm1.Button1Click(Sender: TObject); {!!!}
> >var MyClass : TMyClass;
> >begin
> >     MyClass.Create;
> >     MyClass.s := '';
> >end;

> >end.

        Well the problem with that bit of code is obviously what you
say it is. I'm very puzzled where that snippet _came_ _from_ - I don't
see any code at all in the post I was replying to. I looked for code
three times - I looked back just now and it's still not there. I asked
the guy to show us some code, twice.
        ??? One of those Usenet mysteries??? Or you got it from a later
post of his?

--
David Ullrich

sig.txt not found

Re:Comon you pro's - Long strings as class members


Quote
Erik Marais wrote:
> procedure TForm1.Button1Click(Sender: TObject); {!!!}
> var MyClass : TMyClass;
> begin
>      MyClass.Create;
>      MyClass.s := '';
> end;

That should probably be:

procedure TForm1.Button1Click(Sender: TObject); {!!!}
var MyClass : TMyClass;
begin
     MyClass := TMyClass.Create;
     MyClass.Free
end;

Delphi classes use the reference model; they are not like old-style objects.
MyClass is a pointer to a record on the heap. It is not a record on the stack.

Chris.

Re:Comon you pro's - Long strings as class members


The cause of the problem raises an interesting question for me.

What's the point of having a .Create method in the _instance_ of a class
if it cannot be used (ie you have to use the Create method of the class
because the instance has not be instantiated) ?

Is it because there must be a Create method in the class and so it
automatically gets included in the instance.

But there must be some pointer to the Create method of the putative
instance, otherwise the call (to MyClass.Create) would GPF out.

So why could not that pointer be set (by Borland designers) to refer to
the class Create method.

Can we have some expert comment please ?.

Alan Lloyd
alangll...@aol.com

Re:Comon you pro's - Long strings as class members


This is a multi-part message in MIME format.
--------------EE39656761361430A17EC248
Content-Type: text/plain; charset=us-ascii
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Transfer-Encoding: 7bit

Quote
AlanGLLoyd wrote:
> The cause of the problem raises an interesting question for me.

> What's the point of having a .Create method in the _instance_ of a class
> if it cannot be used (ie you have to use the Create method of the class
> because the instance has not be instantiated) ?

> Is it because there must be a Create method in the class and so it
> automatically gets included in the instance.

> But there must be some pointer to the Create method of the putative
> instance, otherwise the call (to MyClass.Create) would GPF out.

> So why could not that pointer be set (by Borland designers) to refer to
> the class Create method.

> Can we have some expert comment please ?.

var
  o1, o2 : TMyObject;
begin
  o1 := TMyObject.Create;
    // This'll allocate and zero memory for a new TMyObject instance, then call the create method
for the new object
  o1.Create;
    // This'll call the create method for the existing instance of TMyObject
  o2.Create;
    // This'll call the create method for a *non-existing* instance of TMyObject. This corresponds
to calling any other method of
    // an uninitialized object.
end;

Regards,

Erik.

--
Development of applications and drivers for Windows 95 and NT.
Go visit http://www.POBoxes.com/Sperling for some free source!
Check out Delphi Bug Lists at http://www.POBoxes.com/DelphiBugList
PGP public key available at http://www.POBoxes.com/Sperling/pgpkey.txt

Erik Sperling Johansen, Sperl...@POBoxes.com (DeBug Team; checker, monitor)

--------------EE39656761361430A17EC248
Content-Type: text/x-vcard; charset=us-ascii; name="vcard.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Sperling Johansen, Erik
Content-Disposition: attachment; filename="vcard.vcf"

begin:          vcard
fn:             Sperling Johansen, Erik
n:              Sperling Johansen;Erik
org:            Info-Pro
email;internet: Sperl...@POBoxes.com
title:          Developer
x-mozilla-cpt:  ;0
x-mozilla-html: TRUE
end:            vcard

--------------EE39656761361430A17EC248--

Re:Comon you pro's - Long strings as class members


Quote
AlanGLLoyd wrote:

> The cause of the problem raises an interesting question for me.

> What's the point of having a .Create method in the _instance_ of a class
> if it cannot be used (ie you have to use the Create method of the class
> because the instance has not be instantiated) ?

        You _can_ call the Create method of an existing object - there's
a page or two on "constructors" in the docs that spells out exactly what
happens when you call AnObject.Create as opposed to TAClass.Create.

        And you can even call the Create method of an uncreated object.
But saying

var O: TSomeClass;
begin
  O.Create;
end;

has no effect on the contents of the variable O; O is still a pointer
to nothing, so using O for much of anything is likely to cause trouble.
There's nothing illegal about

var O: TSomeClass;
begin
 O.SomeMethod;
end;

, and it doesn't even cause a GPF, _unless_ SomeMethod refers to some
field of O, which of course most methods do. Honest, try this:

type
    THmm=class
     FOops: integer;
     constructor Create;
     procedure Hmm;
    end;

constructor THmm.Create;
begin
showmessage('Hello');
end;

procedure THmm.Hmm;
begin
showmessage('world');
end;

procedure TForm1.Button1Click(Sender: TObject);
var O: THmm;
begin
 O.Create;
end;

procedure TForm1.Button2Click(Sender: TObject);
var O: THmm;
begin
  O.Hmm;
end;

Not very exciting but no GPF either.

        The problem arises when you refer to some field of an
uncreated object, either explicitly or implicitly through some
method call. With the same THmm as above if you say

var O: THmm;
begin
showmessage(inttostr(O.FOops));
end;

there's going to be trouble. The reason is that Delphi looks
for the value of O.FOops at a certain offset from the start of
the structure pointed to by the pointer O, and there is no such
structure - we're looking at a certain offset from a totally random
location in memory, so we better hope for a GPF, because the
alternative is much worse.

        And saying O.Create doesn't change that - this doesn't
allocate memory for a new instance of O (see the docs on AClass.Create
versus AnObject.Create), and even if it did it doesn't modify the
contents of O to point to that block of memory.

Quote
> Is it because there must be a Create method in the class and so it
> automatically gets included in the instance.

> But there must be some pointer to the Create method of the putative
> instance, otherwise the call (to MyClass.Create) would GPF out.

        All methods belong to the class, not the instance - the problem
is that there _is_ no instance.

Quote
> So why could not that pointer be set (by Borland designers) to refer to
> the class Create method.

        AnObject.Create _does_ call the class Create method, as the example
above shows. It does not set the value of AnObject is what it doesn't do.
(And it doesn't actually create anything, because the constructor was
invoked on an object reference instead of a class reference. Why not
make the constructor create something regardless and set the value
of the variable to the returned value? Well, there are reasons related
to how "inherited" works that explain why they didn't want for it to
Create anything, and it can't set the value of the calling object reference
to the created object for the same reason as Free does not set the object
to nil: the method does not know what variable you're using to refer to it.)

--
David Ullrich

sig.txt not found

Re:Comon you pro's - Long strings as class members


On 27 Oct 1997 07:54:12 GMT, alangll...@aol.com (AlanGLLoyd) wrote:

Quote
>What's the point of having a .Create method in the _instance_ of a class
>if it cannot be used (ie you have to use the Create method of the class
>because the instance has not be instantiated) ?

Delphi does not restrict you from calling Create on an instance. The
most common use for that is calling the Create constructor for a base
class, e.g.,

constructor TMyClass.Create;
begin
  inherited Create;  // this calls Create an instance, namely, Self
end;

--
Ray Lischner (http://www.tempest-sw.com/)
Author of "Hidden Paths of Delphi 3: Experts, Wizards, and the Open Tools API"

Re:Comon you pro's - Long strings as class members


On 27 Oct 1997 07:54:12 GMT, alangll...@aol.com (AlanGLLoyd) wrote:

Quote
>The cause of the problem raises an interesting question for me.

>What's the point of having a .Create method in the _instance_ of a class
>if it cannot be used (ie you have to use the Create method of the class
>because the instance has not be instantiated) ?

But it can be used, to create another instance of the class.  You can
use

  dup := existing.Create( ... )

and, if the Create method happens to be a virtual constructor, and
existing has already been created, you'll get a new instance of the
same class as existing, even if you don't know what it is at compile
time.

Duncan Murdoch

Re:Comon you pro's - Long strings as class members


Quote
Duncan Murdoch wrote:

> On 27 Oct 1997 07:54:12 GMT, alangll...@aol.com (AlanGLLoyd) wrote:

> >The cause of the problem raises an interesting question for me.

> >What's the point of having a .Create method in the _instance_ of a class
> >if it cannot be used (ie you have to use the Create method of the class
> >because the instance has not be instantiated) ?

> But it can be used, to create another instance of the class.  

        The constructor can be used, but (at least according to the docs)
not to create another instance. It says "When a constructor is invoked on
an object reference, the constructor acts like a normal procedure method.
This means that a new object is not allocated and cleared, and that the
constructor call does not return an object reference. "

        The following does not do exactly what I expected it to, which
is GPF. It appears to me that it shows that when a constructor is invoked
on an object reference it returns Self (which come to think of it is what
you'd want in the situation they refer to, namely "A constructor is
typically invoked on an object reference only in conjunction with the
inherited keyword to execute an inherited constructor.":

type THmm = class
        FData: integer;
        constructor Create;
      end;

constructor THmm.Create;
begin
inherited Create;
FData:= 42;
end;

procedure TForm1.Button1Click(Sender: TObject);
var b1, b2: THmm;
begin
  b1:= THmm.Create;
  b2:= b1.Create;
  b2.FData:= 24;
  ShowMessage(inttostr(b2.FData));
  ShowMessage(inttostr(b1.FData));
  b2:= b1.Create;
  ShowMessage(inttostr(b2.FData));
  ShowMessage(inttostr(b1.FData));
  if b1 = b2 then
      ShowMessage('that would explain it...');
  b1.Free;
end;

--
David Ullrich

sig.txt not found

Go to page: [1] [2]

Other Threads