Solved

GPF upon setting a property with {$LONGSTRINGS ON}

Posted on 1997-04-07
7
270 Views
Last Modified: 2010-04-06
I don't understand why I would get a
GPF upon running this program with {$LONGSTRINGS ON} and not with
{$LONGSTRINGS OFF}.  The program doesn't do anything spectacular so I
don't see why it generates an EAccessViolation.

program test2;
{$LONGSTRINGS ON}

uses
   classes;

type
   TURL = class
   private
      FData1 : String;
      FData2 : String;
      procedure SetData1(Value : String);
      procedure SetData2(Value : String);
   public
      property Data1 : String read FData1 write SetData1;
      property Data2 : String read FData2 write SetData2;
   end;
   
procedure TURL.SetData1(Value:String);
begin
   FData1 := Value;
end;

procedure TURL.SetData2(Value:String);
begin
   FData2 := Value;
end;

var
   URL : TURL;

begin
   URL.Data1 := 'abc';
   URL.Data2 := 'def';
end.
 

0
Comment
Question by:mvivanco
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 3

Expert Comment

by:mheacock
ID: 1335239
In the LONGSTRINGS ON version, have you tried making the SetData abd SetData1 parameters CONST or VAR?

This may help.
0
 

Author Comment

by:mvivanco
ID: 1335240
I tried both Const and Var and the results are the same, GPF!!!

As you can see by the above code, there is nothing strange about the code.  I am just assigning a value to the property variables.  The interesting thing is that if you remove the Set functions and wrote straight to the variables you still get a GPF!  I tried to find the error from the address return in the GPF but it must be in the VCL code because Delphi cannot find it.  Any other ideas?
0
 
LVL 3

Expert Comment

by:mheacock
ID: 1335241
Longstrings cannot be members of records structures.

Classes are nothing more than records structures that contain methods.  You will have to rewrite your class to use PChars instead of Longstrings.  PChars are essentially the same as
Longstrings, but you have to assign memory for them manually and free them manually.  You also cannot do things like

     szName := 'go';
instead do
     StrCopy(szName, 'go');

If you have to use strings, you'll have to use ShortStrings.

See the Delphi help files on TYPES, then click record structures to read about the limitation.  Classes have the same limitation.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:mvivanco
ID: 1335242
I have just been given the answer to my question and unfortunately your answer was wrong.  The correct answer came from Peter Illes who wrote a paper on converting Delphi 1 code to Delphi 2 (http://ourworld.compuserve.com/homepages/piprog/sgrequ.htm).
Apparently you have to initialize all class instances with a
constructor assignment.  I am investigating it further but so far I have no more GPFs!

Change the main routine as follows:
begin
  // Add the line below and the code will work
  URL := TURL.Create;

  URL.Data1 := 'abc';
  URL.Data2 := 'def';
end.

By the way, I looked in the Delphi help file and the only thing they say is that you cannot have long strings in a variant record.

"Fields in the variant part of a record cannot be of a long string type or of the type Variant. Likewise, fields in the variant part of a record cannot be of a structured type that contains long string or Variant components."
0
 
LVL 3

Expert Comment

by:mheacock
ID: 1335243
Oh well...I'm pretty sure you have to use CREATE in Delphi1
also.  I completely missed your lack of a CREATE call.
0
 

Accepted Solution

by:
lkovac earned 70 total points
ID: 1335244
You need to have the constructor for your object, otherwise strings are not initialized. The long string is basically the four byte pointer. If it is not initially nil (empty) then any assignment (URL.Data1 := 'abc"; for instance) will first try to free the memory pointer is pointing to (which is garbage for you) and that is causing an exception. Constructor will do fine for you in this situation. There may be another situation, you may need to use dynamically allocated strings, like this:
var
  p: pointer;
begin
  GetMem(p, sizeof(string)); {size of long string is 4}
  Initialize(string(p^)); {this will make sure newly allocated string is actually nil pointer initially}
  ... now assign it and use it ...
  Finalize(string(p^)); {this will dealocate memory properly}
  FreeMem(p, sizeof(string));
end;
0
 

Author Comment

by:mvivanco
ID: 1335245
Your answer is kind of correct.  I don't know that I need a constructor but I do need to add URL := TURL.Create to create the object.  You are right in saying that the string pointer is not initialized which will happen when I create the TURL object.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question