Re: String access error in class



"Jamie" <jamie_ka1lpa_not_valid_after_ka1lpa_@xxxxxxxxxxx> wrote in message
news:3GVGj.8$EN.4@xxxxxxxxxxxxxxx
E Sterrett wrote:

I have included a stripped down version of a class I am using to store
configuration data in an ini file.

You might have stripped it down further to a single unoverloaded
constructor.


This works when I am using it from a simple console app. But when I
include it in a larger project, the constructor throws this error:

'Access violation at address 004050FC in module 'app.exe'. Write of
address 00000008'.

A null pointer. With a small offset...


This happens on the line: ComputerName:='test';

....at first glance consistent with the ComputerName field.


Obviously 00000008 is not a valid address. But I thought delphi handles
string address automatically.

Strings, yes. Objects, no.


What have I done wrong?

Probably calling a constructor on an object variable somewhere, instead of
on a class reference and storing the returned object in the variable.

Look for code that says 'Config.Create' instead of
'Config:=TConfig.Create'. If Config still happens to be nil, that would
cause these exact symptoms.

You don't show the code that creates the object. It seems somewhat
likely that you got it right in the console application, then messed
up the second time.

Lots of former C++ programmers make this mistake, through expecting
objects to be automatically allocated on the stack. In Delphi, object
variables are references, uninitialised, and the objects themselves are
_always_ created on the heap. And also always explicitly so, they are
never created automatically. Nor freed automatically, either.


unit Configuration;

interface

uses windows,inifiles,sysutils;

type
TConfig = Class(TObject)
public
FileName:string;
ComputerName:String;

As a rule, fields should be private, not public.

If you need outside access, make properties. (If you don't, make
properties anyway, but make them protected. Then never touch the
fields again.)


constructor Create(); overload;
constructor Create(FN:String); overload;
end;

var
IniFile : TIniFile;

implementation

constructor TConfig.Create(Fn:string)overload;
begin
IniFile := TIniFile.Create(Fn);

IniFile is a global variable. That can't be right. And it looks like
a form variable as created by the IDE, but for a class that isn't
apparent and may no longer exist.


ComputerName:='test';
filename:=fn;
end;

constructor TConfig.Create()overload;
begin
Create(Paramstr(0)+'.ini');
end;

end.

Try calling the inherited create first maybe?

That's a good habit but I don't think it makes a difference in this
case. (I still do think it _matters_. You should always call an
inherited constructor.)

Constructors can be called in either of two ways: on a class reference
or on an instance. The first case is handled by creating a new, blank
instance first through compiler magic, then calling the constructor
on the new instance as per the second case.

TObject.Create does nothing, so you don't lose any code by not
calling it. But that's just coincidence. Forgetting to call the
inherited constructor is dangerous and it is far better to always
call it as a matter of principle.

Groetjes,
Maarten Wiltink


.



Relevant Pages

  • Re: String access error in class
    ... configuration data in an ini file. ... But when I include it in a larger project, the constructor throws this error: ... constructor Create; overload; ... IniFile: TIniFile; ...
    (alt.comp.lang.borland-delphi)
  • Class events
    ... which contains configuration data for my ... Unfortunately I cannot use a static implementation of the class, ... requires a constructor. ... Dave ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Create new object with the same subsubclass
    ... classtype of TObject. ... you need to use a virtual constructor and a class ... this is resolved to a class reference in a variable of TComponentClass ... Create is called on that class reference, and the compiler knows ...
    (comp.lang.pascal.delphi.misc)
  • Re: String access error in class
    ... Constructors can be called in either of two ways: on a class reference ... instance first through compiler magic, then calling the constructor ...
    (alt.comp.lang.borland-delphi)
  • Re: Instantiate class reference...
    ... but the constructor for TncJob is never ... Is the constructor TncObject.Create virtual? ... Of course this means that the constructors of all TncObject descendants ... an example of creation of instances through class reference). ...
    (borland.public.delphi.language.objectpascal)