Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Set all record variables to 0 or empty string

82 views
Skip to first unread message

Richard Simpson

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
I have a record with about 20 variables of different types, such as
strings, integers, and boolean. If I want to re-initialize all the
variables (setting strings as empty, integers as 0, booleans as
false), is there an alternative to setting each variable individually?


Alexander Mueller

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to

var myrecord:Tmyrecord;

ZeroMemory(@myrecord,SizeOf(Tmyrecord));

Alex
--
** Pepsi Cola and Animal protection **
** http://www.pepsibloodbath.com/ **

Author of the free Chatsystem PINO!
Available at http://pino.cjb.net

BlueGI

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
Yep, use the FillChar procedure.

FillChar(MyRecord, SizeOf(MyRecord), 0);


"Richard Simpson" <Richard...@mail.house.gov> wrote in message
news:869kii$ij...@bornews.borland.com...

Rudy Velthuis

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
Alexander Mueller wrote...

>Richard Simpson wrote:
>>
>> I have a record with about 20 variables of different types, such as
>> strings, integers, and boolean. If I want to re-initialize all the
>> variables (setting strings as empty, integers as 0, booleans as
>> false), is there an alternative to setting each variable individually?
>
>var myrecord:Tmyrecord;
>
>ZeroMemory(@myrecord,SizeOf(Tmyrecord));

Or:

FillChar(MyRecord, SizeOf(MyRecord), #0);

--
Rudy Velthuis

philippe_ranger

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
<<Richard:

I have a record with about 20 variables of different types, such as
strings, integers, and boolean. If I want to re-initialize all the
variables (setting strings as empty, integers as 0, booleans as
false), is there an alternative to setting each variable individually?
>>

Alex's and Blues's mass-zappings are *guaranteed* to create memory leaks and
possibly worse. You can mass-zap, but before you do it, call Finalize on
those records. Then, after zapping, call Initialize. Essential.

PhR


Greg Chapman

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
On Fri, 21 Jan 2000 07:57:11 -0500, "Richard Simpson"
<Richard...@mail.house.gov> wrote:

>I have a record with about 20 variables of different types, such as
>strings, integers, and boolean. If I want to re-initialize all the
>variables (setting strings as empty, integers as 0, booleans as
>false), is there an alternative to setting each variable individually?

If the strings are Delphi's long strings (i.e., the default string type), DO NOT
USE fillchar to zero out the record. At least not immediately. You have to do
something like:

Finalize(MyRecordVariable);
fillchar(MyRecordVariable, sizeof(MyRecordVariable), 0);

The Finalize call is necessary to make sure the long strings have their
reference counts decremented correctly (including freeing them if appropriate).

Greg Chapman


Christopher Pall

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
Doesn't that only apply to dynamically sized variables?

"Philippe Ranger" wrote:

> <<Richard:


> I have a record with about 20 variables of different types, such as
> strings, integers, and boolean. If I want to re-initialize all the
> variables (setting strings as empty, integers as 0, booleans as
> false), is there an alternative to setting each variable individually?
> >>
>

> Alex's and Blues's mass-zappings are *guaranteed* to create memory leaks and
> possibly worse. You can mass-zap, but before you do it, call Finalize on
> those records. Then, after zapping, call Initialize. Essential.
>
> PhR

--
Chris

Stuart C. Naifeh

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
> Doesn't that only apply to dynamically sized variables?

or records containing dynamically sized variables, such as strings.

Regards,
Stuart

philippe_ranger

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
<<Rudy:
FillChar(MyRecord, SizeOf(MyRecord), #0);
>>

You're zapping ansiString refs, Rudy.

PhR

Stuart C. Naifeh

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
FillChar will take a byte as well as a char so #0 could be simply 0.

Stuart

"Rudy Velthuis" <rvel...@gmx.de> wrote in message
news:MPG.12f29d3ec...@bornews.borland.com...


> Alexander Mueller wrote...
> >Richard Simpson wrote:
> >>

> >> I have a record with about 20 variables of different types, such as
> >> strings, integers, and boolean. If I want to re-initialize all the
> >> variables (setting strings as empty, integers as 0, booleans as
> >> false), is there an alternative to setting each variable individually?
> >

Rudy Velthuis

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
<Philippe Ranger> wrote...

><<Rudy:
>FillChar(MyRecord, SizeOf(MyRecord), #0);
>>>
>
>You're zapping ansiString refs, Rudy.

Yes, I noticed later on (alerted by your message).
--
Rudy Velthuis

philippe_ranger

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
<<Christopher:

Doesn't that only apply to dynamically sized variables?
>>

Yes, anything holding ref-counted vars at any level of nesting. Richard said
he had strings in his record, and left the list open. Ref-counted vars are
ansiStings, wideStrings, interfaces, variant arrays and dynArrays -- for
now.

The policy should be to always finalize and initialize unless you
specifically know you do not have to. In this case, because the zapping was
to zero, initialization wasn't needed, actually.

PhR

Richard Simpson

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
Does it make any difference whether my variable is dynamically
allocated?

I created a record type, then just declared one instance of it in my
form class declaration. At various times, I want to re-initialize all
the variables and then set some of them to particular values.

I knew about FillChar but thought it might be dangerous in this
situation. From reading the messages, it appears that here is what I
should do:

Finalize(MyRec);
FillChar(MyRec, SizeOf(MyRec), 0);
Initialize(MyRec);
MyRec.Var3 := 'Hello';
MyRec.Var5 := True;
MyRec.Var6 := 5;
if MyRec.Var1 = '' then // Should be true?

How's that? Safe? No memory leaks?


Rudy Velthuis

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
<Philippe Ranger> wrote...

>Ref-counted vars are ansiStings, wideStrings,

The WideString type is not reference counted. The OPLG says about
WideString:

<<
The WideString type represents a dynamically allocated string of 16-bit
Unicode characters. In most respects it is similar to AnsiString, but it
is less efficient because it does not implement reference-counting and
copy-on-write semantics.
>>

Somewhere else the help says:

<<
WideStrings are dynamically allocated with a maximum length limited only
by available memory. However, wide strings are not reference counted. The
dynamically allocated memory that contains the string is deallocated when
the wide string goes out of scope. In all other respects wide strings
possess the same attributes as long strings. The WideString type is
denoted by the predefined identifier WideString.
>>

So there. <g>

When was the last time *you* read the OPLG?

<g,d&r>
--
Rudy Velthuis

philippe_ranger

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
<<Richard:

Does it make any difference whether my variable is dynamically
allocated?
>>

No.

<<
Finalize(MyRec);
FillChar(MyRec, SizeOf(MyRec), 0);
Initialize(MyRec);
MyRec.Var3 := 'Hello';
MyRec.Var5 := True;
MyRec.Var6 := 5;
if MyRec.Var1 = '' then // Should be true?

How's that? Safe? No memory leaks?
>>

As long as you fill with zeros, you can skip the Initialize -- but that's
not the way the RTL does it, so putting the Initialize in there certainly
does no harm.

The last line is guaranteed to be true.

And this is safe and leak-less.

PhR

philippe_ranger

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
<<Rudy:

The WideString type is not reference counted. The OPLG says about
WideString:
>>

My mistake.

<<
When was the last time *you* read the OPLG?
>>

Actually, I read your quote a week ago. It's just that I had this idea that
Bstr's are ref-counted. I remember figuring out that if you copy on
assignment, you don't need ref counts, but, well, I forgot.

PhR

John Herbster

unread,
Jan 21, 2000, 3:00:00 AM1/21/00
to
This makes me appreciate ShortStrings all the more. When they will do the
job, they are simple, easy to understand, thread safe, and faster. <g>

philippe_ranger

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to
<<John:

When they will do the
job, they are simple, easy to understand, thread safe, and faster. <g>
>>

But remember that where D2-D4 had separate basic string ops for
shortstrings, D5 now converts back and forth from longstring for stuff like
concatenation.

PhR

Jean-Marie Pierrard

unread,
Jan 22, 2000, 3:00:00 AM1/22/00
to
Hi Philippe,

You are talking about dynArrays. I have Delphi 3 and don't see this type of
variable. Is it a resizeable array like Visual Basic arrays ?

Thank you in advance for the advice!

Jean-Marie.

<Philippe Ranger> wrote in message news:86ad4v$j5...@bornews.borland.com...

Sebastian Moleski

unread,
Jan 23, 2000, 3:00:00 AM1/23/00
to
<Philippe Ranger> schrieb in im Newsbeitrag:
86bfol$jf...@bornews.borland.com...

Really? I wonder who made that decision and for what reason. It surely
didn't make the compiler more slim or something.

Sebastian Moleski


Sebastian Moleski

unread,
Jan 23, 2000, 3:00:00 AM1/23/00
to
[snip]
> Finalize(MyRec);
> FillChar(MyRec, SizeOf(MyRec), 0);
[snip]

> As long as you fill with zeros, you can skip the Initialize -- but that's
> not the way the RTL does it, so putting the Initialize in there certainly
> does no harm.
>
> The last line is guaranteed to be true.
>
> And this is safe and leak-less.

Unless MyRec is a pointer to a record in which case your FillChar
call must look like this:

FillChar(MyRec^, SizeOf(MyRec^), 0);

Otherwise, you just zero the pointer which most likely wasn't what
you wanted to do. (The compiler won't stop you from doing that.)

Sebastian Moleski


philippe_ranger

unread,
Jan 23, 2000, 3:00:00 AM1/23/00
to
<<Sebastian:

Really? I wonder who made that decision and for what reason. It surely
didn't make the compiler more slim or something.
>>

It's not my discovery. It was discussed here in Sept. or Oct., iirc. Perhaps
it's to plug into the heightened (and costly) thread safety of ansiStrings.

PhR

John Herbster

unread,
Jan 23, 2000, 3:00:00 AM1/23/00
to
Could short strings be unsafe? Is it easy to explain how?

<Philippe Ranger> wrote ...
> {Why] ... [perhaps] it's to plug into the heightened

philippe_ranger

unread,
Jan 23, 2000, 3:00:00 AM1/23/00
to
<<John:

Could short strings be unsafe? Is it easy to explain how?
>>

What's unsafe is changing a shared variable. With ansiStrings, this gets
tricky, because an apparently benign assignment does change the thing being
assigned from and worse, even changes the *previous* value (decrements its
ref count). Hence the kevlar protection newly built into D5.

There's nothing similar for shortStrings. However, where a benign assignment
was unsafe with ansiStrings, now that the assignment is safe, presto,
*changing* ansiStrings is also safe (write on copy, so the "changed" string
is unchanged to its other references). But changing shortStrings isn't. If
you assign a new value to a shortString, the whole of it cannot be changed
at once (as happens with an ansiString ref).

In other words, an ansiString "var" is actually a pointer and you don't
change the object it points to, except for the ref count, you point it to a
new object. The same operation on an apparently-similar shortstring changes
the one actual object shared by all vars.

So, somehow, the simplest way to give shortStrings the same thread safety as
ansiStrings in D5 may have been to use the assignment-lock of ansiStrings to
read and write shortStrings during operations on them.

PhR

filippo

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
And if I have to set zero just one variable? (for example the third of all
records....)
can be done just by one procedure for all types?
filippo

--
-------------------------------------------------------
Filippo Forlani
web page: http://space.tin.it/arte/fiforlan
e.mail fil...@tin.it

"Alexander Mueller" <al...@gmx.at> wrote in message
news:3888582E...@gmx.at...


> Richard Simpson wrote:
> >
> > I have a record with about 20 variables of different types, such as
> > strings, integers, and boolean. If I want to re-initialize all the
> > variables (setting strings as empty, integers as 0, booleans as
> > false), is there an alternative to setting each variable individually?
>
> var myrecord:Tmyrecord;
>
> ZeroMemory(@myrecord,SizeOf(Tmyrecord));
>

John Herbster

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
Philippe, Thank you for the attempt at a explanation, but I am missing
something. If I assume the usual case of short string variables that
are only referenced by one thread at a time, or if they are used by
more than one thread, we protect them by having the usage in a
critical section. Then, I wonder, how can the short strings be
unsafe? (Don't hurry with an answer, I need to do some experiments
that may resolve this question.)

<Philippe Ranger> wrote


> What's unsafe is changing a shared variable.

With short strings, what's shared?

> ... If you assign a new value to a shortString,


> the whole of it cannot be changed at once

So?

> ... *somehow*, the simplest way to give shortStrings the same thread
safety as
> ansiStrings in D5 *may* have been to use the assignment-lock of


ansiStrings to
> read and write shortStrings during operations on them.

I think that we are speculating to much. I will try some
short strings by speed tests and looking at the machine
code later and let you know what I find. Regards, John H


philippe_ranger

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
<<John:

If I assume the usual case of short string variables that
are only referenced by one thread at a time, or if they are used by
more than one thread, we protect them by having the usage in a
critical section.
>>

That's the point. The same operation on an ansiString doesn't require a
critical section in D5, as the only truly affected element is the ref count,
and this has its own automatic crit-sect protection. So, to avoid people's
forgetting they still need one for shortstrings, Borland may have elected to
give them their own automatic critical section, and found that the easiest
way to this was to convert to and from ansiString.

<<
With short strings, what's shared?
>>

Talking about shared shortstrings.

<<<PhR:


... If you assign a new value to a shortString, the whole of it cannot be
changed at once
>>>

<<John:
So?
>>

So, as you said at the beginning, it needs a crit sect if shared. And, like
ansiStrings, it gets it, share or no share, without programmer involvement.

PhR

0 new messages