For Programmers: Free Programming Magazines  


Home > Archive > Visual Basic > April 2005 > How to sneak around a NULL value









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author How to sneak around a NULL value
PaulB

2005-04-26, 3:56 pm

Hi Folks,

I have a short routine that will reverse the "Order-of-Characters" in
a text string. ( part of learning about encryption).

It works nicely... until you send a Null value.

The problem is because I use a "For i = 1 to nCounter" kind of loop
to work the passed string into its new "Order-of-Character". nCounter
is the string length which is zero.
I have included an IF nCounter=0 then exit sub, but this is a function
and VB won't allow that cheat.

What can I do to resolve?




Thanks,

Paul
( This darn program refuses to do what I want
it to. It ONLY does what I tell it to...
and reluctantly. Remainds me of Bart Simpson )
MP

2005-04-26, 3:56 pm


<PaulB> wrote in message news:mvss619kbg8vc3o0juj3iqsaffio32ht9j@
4ax.com...
> Hi Folks,
> I have included an IF nCounter=0 then exit sub, but this is a function
> and VB won't allow that cheat.
>
> What can I do to resolve?
>


IF nCounter=0 then exit function???


Charlie

2005-04-26, 3:56 pm

The syntax is

Exit Function


"PaulB" wrote:

> Hi Folks,
>
> I have a short routine that will reverse the "Order-of-Characters" in
> a text string. ( part of learning about encryption).
>
> It works nicely... until you send a Null value.
>
> The problem is because I use a "For i = 1 to nCounter" kind of loop
> to work the passed string into its new "Order-of-Character". nCounter
> is the string length which is zero.
> I have included an IF nCounter=0 then exit sub, but this is a function
> and VB won't allow that cheat.
>
> What can I do to resolve?
>
>
>
>
> Thanks,
>
> Paul
> ( This darn program refuses to do what I want
> it to. It ONLY does what I tell it to...
> and reluctantly. Remainds me of Bart Simpson )
>

Rick Rothstein

2005-04-26, 3:56 pm

> I have included an IF nCounter=0 then exit sub, but this
> is a function and VB won't allow that cheat.


VB does have an Exit Function statement available to quit out of
functions in the same way Exit Sub quits out of Sub(routines).

Rick - MVP

Karl E. Peterson

2005-04-26, 3:56 pm

PaulB wrote:
> Hi Folks,
>
> I have a short routine that will reverse the "Order-of-Characters" in
> a text string. ( part of learning about encryption).
>
> It works nicely... until you send a Null value.


Do you really mean (VB parlance) an empty string?

> The problem is because I use a "For i = 1 to nCounter" kind of loop
> to work the passed string into its new "Order-of-Character". nCounter
> is the string length which is zero.
> I have included an IF nCounter=0 then exit sub, but this is a function
> and VB won't allow that cheat.


Ummm, how about Exit Function?

I'd likely structure the function like this, myself:

If Len(StrToRev) Then
' Perform the reversal, and assign return value.
End If

That'd end up returning an empty string when passed an empty string.

> What can I do to resolve?


Maybe if you showed the code you're having troubles with, actual proposals could be
offered?

Later... Karl
--
Working Without a .NET?
http://classicvb.org/petition


Veign

2005-04-26, 3:56 pm

First off: Null and Zero length string are two different things. You are
talking about a zero length string in this case.

Second: Just test the len of the string prior to the looping routine.

Like:
If Len(MyString) = 0 Then Exit Sub

'Looping Code here

--
Chris Hanscom - Microsoft MVP (VB)
Veign's Resource Center
http://www.veign.com/vrc_main.asp
--
Read. Decide. Sign the petition to Microsoft.
http://classicvb.org/petition/


<PaulB> wrote in message news:mvss619kbg8vc3o0juj3iqsaffio32ht9j@
4ax.com...
> Hi Folks,
>
> I have a short routine that will reverse the "Order-of-Characters" in
> a text string. ( part of learning about encryption).
>
> It works nicely... until you send a Null value.
>
> The problem is because I use a "For i = 1 to nCounter" kind of loop
> to work the passed string into its new "Order-of-Character". nCounter
> is the string length which is zero.
> I have included an IF nCounter=0 then exit sub, but this is a function
> and VB won't allow that cheat.
>
> What can I do to resolve?
>
>
>
>
> Thanks,
>
> Paul
> ( This darn program refuses to do what I want
> it to. It ONLY does what I tell it to...
> and reluctantly. Remainds me of Bart Simpson )



Ken Halter

2005-04-26, 3:56 pm

<PaulB> wrote in message news:mvss619kbg8vc3o0juj3iqsaffio32ht9j@
4ax.com...
> Hi Folks,
>
> I have a short routine that will reverse the "Order-of-Characters" in
> a text string. ( part of learning about encryption).
>
> It works nicely... until you send a Null value.
>
> The problem is because I use a "For i = 1 to nCounter" kind of loop


'=============
Private Sub Form_Load()
Dim i As Integer
Dim nCounter As Integer

nCounter = 0

For i = 1 To nCounter
MsgBox "this won't run if nCounter = 0"
MsgBox ""
MsgBox "But, if it did, you can use Exit For"
MsgBox ""
MsgBox "Depending on the code after the Next below"
MsgBox "You can use Exit For instead of Exit Sub"
MsgBox "Maybe I misread the question too."
MsgBox ""
MsgBox "Exit Subs can be a pain imo because they"
MsgBox "allow more than one way out of a procedure"
MsgBox "and they're easily missed so they make"
MsgBox "debugging harder."
Next

End Sub
'=============

--
Ken Halter - MS-MVP-VB - http://www.vbsight.com
Sign up now to help keep VB support alive - http://classicvb.org/petition
Please keep all discussions in the groups..


PaulB

2005-04-26, 3:56 pm

Thanks,

I have already kicked myself for that question.

By the way, what "IS" the difference between a zero length string and
a NULL value string?


Thanks,

Paul
( This darn program refuses to do what I want
it to. It ONLY does what I tell it to...
and reluctantly. Remainds me of Bart Simpson )
Jeff Johnson [MVP: VB]

2005-04-26, 3:56 pm


<PaulB> wrote in message news:f2vs61dfdp2eqk74s50o18p1oru377tb7a@
4ax.com...

> By the way, what "IS" the difference between a zero length string and
> a NULL value string?


Nothing, because the question is flawed. There is no such thing as a "NULL
value string." Strings CANNOT contain the value Null. Only Variants (and
data types which are implemented as Variants behind the scenes, like Date)
can contain Null.

What you're talking about (the "null string") comes from C terminology and
refers to a string that contains nothing but the terminating ASCII 0 (called
the Null character). We try to avoid that term in VB simply because Null is
such a commonly-used value and it gets confusing, as you have just
experienced.


Tony Proctor

2005-04-26, 8:55 pm

An empty string is normally a pointer to an empty BSTR (i.e. the piece of
memory representing strings in Unicode). This has a normal length field
(containing 0) and an immediate NULL (=0) terminator (i.e. no text data in
it)

The constant represented by vbNullString is often referred to as a "null
string". It is different in that it is actually an empty pointer rather than
a pointer to an empty string. If you call StrPtr() on vbNullString then
you'll see it returns 0 rather than a pointer to the empty BSTR mentioned
above.

Tony Proctor

<PaulB> wrote in message news:f2vs61dfdp2eqk74s50o18p1oru377tb7a@
4ax.com...
> Thanks,
>
> I have already kicked myself for that question.
>
> By the way, what "IS" the difference between a zero length string and
> a NULL value string?
>
>
> Thanks,
>
> Paul
> ( This darn program refuses to do what I want
> it to. It ONLY does what I tell it to...
> and reluctantly. Remainds me of Bart Simpson )



PaulB

2005-04-26, 8:55 pm

Thank you for your comments, but now I'm scared.

I'm wondering then if there is a Logic-SNAFU in my expectations then. I really don't want to get to hour-650 and find
out that I've had a lot of fun but need to address a fundamental brain-fart embedded in my thinking...
( Like forgetting all about how useful account numbers might have been, were they there )


This is a "foundation" of what I am trying to do:

Text-Type fields of the table is stored in an encoded form, encoded meaning a simple character substitution thing.
That's easy because there are sENCRYPT and sDECRYPT functions.

However.... myString could be NULL

I get killed with all of these expressions. It seems as if "myString" can't even be used as a parameter if the thing is
NULL

textBox.text= sDECRYPT( myString, Len(myString) )

textBox.text= sDECRYPT( myString, IIF( myString=NULL, 0, Len( myString) ) )

textBox.text= sDECRYPT( myString, IIF( IsNull(rsData1!Wage), 0, Len(rsData1!Wage) ) )

How do I refer to a NULL, and perhaps... "why" does it exist?
Thanks,

Paul
( This darn program refuses to do what I want
it to. It ONLY does what I tell it to...
and reluctantly. Remainds me of Bart Simpson )
Tony Proctor

2005-04-26, 8:55 pm

The rsData1!Wage type of NULL is coming from the database Paul. Columns in a
relational database can be given a NULL status is they don't contain
anything.

You cannot use IIf() to test using IsNull, as you've tried to do here. IIf()
evaluated both true & false values, irrespective of the condition. Hence,
you call will always cause an error when processing a NUL value

Tony Proctor

<PaulB> wrote in message news:tv1t61hng52rps6sa34s07ssr1drmol5o8@
4ax.com...
> Thank you for your comments, but now I'm scared.
>
> I'm wondering then if there is a Logic-SNAFU in my expectations then. I

really don't want to get to hour-650 and find
> out that I've had a lot of fun but need to address a fundamental

brain-fart embedded in my thinking...
> ( Like forgetting all about how useful account numbers might have been,

were they there )
>
>
> This is a "foundation" of what I am trying to do:
>
> Text-Type fields of the table is stored in an encoded form, encoded

meaning a simple character substitution thing.
> That's easy because there are sENCRYPT and sDECRYPT functions.
>
> However.... myString could be NULL
>
> I get killed with all of these expressions. It seems as if "myString"

can't even be used as a parameter if the thing is
> NULL
>
> textBox.text= sDECRYPT( myString, Len(myString) )
>
> textBox.text= sDECRYPT( myString, IIF( myString=NULL, 0, Len(

myString) ) )
>
> textBox.text= sDECRYPT( myString, IIF( IsNull(rsData1!Wage), 0,

Len(rsData1!Wage) ) )
>
> How do I refer to a NULL, and perhaps... "why" does it exist?
> Thanks,
>
> Paul
> ( This darn program refuses to do what I want
> it to. It ONLY does what I tell it to...
> and reluctantly. Remainds me of Bart Simpson )



Jim Edgar

2005-04-26, 8:55 pm


<PaulB> wrote in message news:tv1t61hng52rps6sa34s07ssr1drmol5o8@
4ax.com...
> Thank you for your comments, but now I'm scared.
>
> I'm wondering then if there is a Logic-SNAFU in my expectations then. I

really don't want to get to hour-650 and find
> out that I've had a lot of fun but need to address a fundamental

brain-fart embedded in my thinking...
> ( Like forgetting all about how useful account numbers might have been,

were they there )
>
>
> This is a "foundation" of what I am trying to do:
>
> Text-Type fields of the table is stored in an encoded form, encoded

meaning a simple character substitution thing.
> That's easy because there are sENCRYPT and sDECRYPT functions.
>
> However.... myString could be NULL
>
> I get killed with all of these expressions. It seems as if "myString"

can't even be used as a parameter if the thing is
> NULL
>
> textBox.text= sDECRYPT( myString, Len(myString) )
>
> textBox.text= sDECRYPT( myString, IIF( myString=NULL, 0, Len(

myString) ) )
>
> textBox.text= sDECRYPT( myString, IIF( IsNull(rsData1!Wage), 0,

Len(rsData1!Wage) ) )
>


If you have control over the source code of the sENCRYPT and sDECRYPT
functions then redeclare them without the string length argument. Check for
null values and string length inside of the functions:

Function sDECRYPT(myString) As String
Dim lLen As Long
If Not IsNull(myString) Then
lLen = Len(myString)
' Decrypt code goes here
End If
End Function

Otherwise you'll need to check for null values before you call the
encryption functions:

If Not IsNull(Data1!Wage.Value) Then
TextBox.Text = sDECRYPT(Data1!Wage.Value, Len(Data1!Wage.Value))
End If

Hope I'm on the right track,

Jim Edgar


YYZ

2005-04-26, 8:55 pm

<PaulB> wrote in message news:tv1t61hng52rps6sa34s07ssr1drmol5o8@
4ax.com...
> I get killed with all of these expressions. It seems as if "myString"
> can't even be used as a parameter if the thing is
> NULL
>
> textBox.text= sDECRYPT( myString, Len(myString) )
>
> textBox.text= sDECRYPT( myString, IIF( myString=NULL, 0, Len(
> myString) ) )
>
> textBox.text= sDECRYPT( myString, IIF( IsNull(rsData1!Wage), 0,
> Len(rsData1!Wage) ) )


In addition to what Tony and Jim said, you can try this:

textbox.text = sDECRYPT( "" & rsData1!Wage, len("" & rsData1!Wage))

What you are doing is appending an empty string in front of the value of
rsData1!Wage -- which forces VB to convert rsData1!Wage to a string (and it
can do so with a null if it wants), and then finally what is passed to
sDECRYPT is a string. If rsData1!Wage was null, it gets converted to an
empty string.

Now, if sDECRYPT doesn't like taking in an empty string, that's another
issue. But it won't choke on NULL anymore...

Matt


Ken Halter

2005-04-26, 8:55 pm

"YYZ" <none@none.com> wrote in message
news:OQk9EFqSFHA.1404@TK2MSFTNGP09.phx.gbl...
> <PaulB> wrote in message
> news:tv1t61hng52rps6sa34s07ssr1drmol5o8@
4ax.com...
>
> In addition to what Tony and Jim said, you can try this:
>
> textbox.text = sDECRYPT( "" & rsData1!Wage, len("" & rsData1!Wage))
>


That.... and move the Len call to the function itself, so the 'sDECRYPT'
call is much cleaner, faster and easier to write... unless there's a reason
to keep it separate.

--
Ken Halter - MS-MVP-VB - http://www.vbsight.com
Sign up now to help keep VB support alive - http://classicvb.org/petition
Please keep all discussions in the groups..


J French

2005-04-26, 8:55 pm

On Tue, 26 Apr 2005 20:04:57 +0100, "Tony Proctor"
<tony_proctor@aimtechnology_NoMoreSPAM_.com> wrote:

>An empty string is normally a pointer to an empty BSTR (i.e. the piece of
>memory representing strings in Unicode). This has a normal length field
>(containing 0) and an immediate NULL (=0) terminator (i.e. no text data in
>it)
>
>The constant represented by vbNullString is often referred to as a "null
>string". It is different in that it is actually an empty pointer rather than
>a pointer to an empty string. If you call StrPtr() on vbNullString then
>you'll see it returns 0 rather than a pointer to the empty BSTR mentioned
>above.


Tony, run up this little sample :-

Private Sub Command1_Click()
Dim S$
Me.Print StrPtr(S$)
S$ = ""
Me.Print StrPtr(S$)
End Sub

Karl E. Peterson

2005-04-26, 8:55 pm

J French wrote:
> On Tue, 26 Apr 2005 20:04:57 +0100, "Tony Proctor"
> <tony_proctor@aimtechnology_NoMoreSPAM_.com> wrote:
>
>
> Tony, run up this little sample :-
>
> Private Sub Command1_Click()
> Dim S$
> Me.Print StrPtr(S$)
> S$ = ""
> Me.Print StrPtr(S$)
> End Sub


Not sure I get your point? Maybe you'd like to run this little sample?

Public Sub foo()
Dim S$
Debug.Print StrPtr(S$)
Debug.Print S$ = vbNullString
S$ = ""
Debug.Print StrPtr(S$)
End Sub

Later... Karl
--
Working Without a .NET?
http://classicvb.org/petition


Ken Halter

2005-04-26, 8:55 pm

"Karl E. Peterson" <karl@mvps.org> wrote in message
news:OShbdYqSFHA.140@TK2MSFTNGP10.phx.gbl...
>
> Not sure I get your point? Maybe you'd like to run this little sample?
>
> Public Sub foo()
> Dim S$
> Debug.Print StrPtr(S$)
> Debug.Print S$ = vbNullString
> S$ = ""
> Debug.Print StrPtr(S$)
> End Sub


heh... well, if we're looking at samples here, try this one... it's a very
4-6 axis robot simulator written in VB6. (view first link, download
second link 'cause the first has a bug)

A 6 axis and 4 axis Scara Robot Simulator
http://www.planet-source-code.com/v...=51247&lngWId=1

The updated version is here (the link above's more for an english version of
the description and a screen print)
http://5axes.free.fr/devel_robot.htm

Very imo.

> Later... Karl
> --
> Working Without a .NET?
> http://classicvb.org/petition
>



--
Ken Halter - MS-MVP-VB - http://www.vbsight.com
Sign up now to help keep VB support alive - http://classicvb.org/petition
Please keep all discussions in the groups..


Karl E. Peterson

2005-04-26, 8:55 pm

Ken Halter wrote:
> heh... well, if we're looking at samples here, try this one... it's a
> very 4-6 axis robot simulator written in VB6. (view first link,
> download second link 'cause the first has a bug)


Okay, now we're definitely spiraling downward... <g>
--
Working Without a .NET?
http://classicvb.org/petition


Ken Halter

2005-04-26, 8:55 pm

"Karl E. Peterson" <karl@mvps.org> wrote in message
news:uTlrMkqSFHA.2556@TK2MSFTNGP12.phx.gbl...
> Ken Halter wrote:
>
> Okay, now we're definitely spiraling downward... <g>
> --
> Working Without a .NET?
> http://classicvb.org/petition


Well.... I was looking for an excuse (any excuse would do) to post that
sample <g>

--
Ken Halter - MS-MVP-VB - http://www.vbsight.com
Sign up now to help keep VB support alive - http://classicvb.org/petition
Please keep all discussions in the groups..


Karl E. Peterson

2005-04-26, 8:55 pm

Ken Halter wrote:
> "Karl E. Peterson" <karl@mvps.org> wrote in message
> news:uTlrMkqSFHA.2556@TK2MSFTNGP12.phx.gbl...
>
> Well.... I was looking for an excuse (any excuse would do) to post
> that sample <g>


Takes 'em where you gets 'em. :-)
--
Working Without a .NET?
http://classicvb.org/petition


J French

2005-04-26, 8:55 pm

On Tue, 26 Apr 2005 14:22:53 -0700, "Karl E. Peterson" <karl@mvps.org>
wrote:
<snip>

>Not sure I get your point? Maybe you'd like to run this little sample?
>
> Public Sub foo()
> Dim S$
> Debug.Print StrPtr(S$)
> Debug.Print S$ = vbNullString
> S$ = ""
> Debug.Print StrPtr(S$)
> End Sub


Yes
- it is interesting that an unused string starts life as a
vbNullString
- and can become one again
Karl E. Peterson

2005-04-26, 8:55 pm

J French wrote:
> On Tue, 26 Apr 2005 14:22:53 -0700, "Karl E. Peterson" <karl@mvps.org>
> wrote:
> <snip>
>
>
> Yes
> - it is interesting that an unused string starts life as a
> vbNullString
> - and can become one again


What goes around comes around, eh? As we've seen, a vbNullString is just a string
variable that points to nothing. I never really realized it before, but it's not
unlike using New in an object declaration! That's almost disturbing.
--
Working Without a .NET?
http://classicvb.org/petition


J French

2005-04-27, 3:55 am

On Tue, 26 Apr 2005 15:58:09 -0700, "Karl E. Peterson" <karl@mvps.org>
wrote:

<snip>

>
>What goes around comes around, eh? As we've seen, a vbNullString is just a string
>variable that points to nothing. I never really realized it before, but it's not
>unlike using New in an object declaration! That's almost disturbing.


It kind of figures that it starts life like that
- as zapping the stack is the most efficient way of initializing
variables to 'nothing'

However it is a bit disturbing that a zero length string can be either
a vbNullString or a pointer to a zero length string

Not that it matters a jot within VB, but there are plenty of
ramifications in the APIs
- are you feeling queezy - I certainly am

Personally I reckon they should have stuck with "" really being Null
- it does not look as if a string's memory is reused if its length is
reduced
- perhaps they were aiming to retro-fit that later
- they certainly re-use memory blocks for Arrays


Tony Proctor

2005-04-27, 8:56 am

As a separate issue, not related to this NULL problem, you really shouldn't
pass "encrypted text" in a String variable. There are several reasons for
this (e.g. have a read of
http://www.google.ie/groups?safe=of...r=lang_en&hl=en
if you're interested), but I don't want to obscure this thread with too much
on the subject. Ideally, your Encrypt function should return a Byte array,
and your Decrypt function should accept a Byte array argument. It's good
practice to always think of encrypted text as "not text anymore". Maybe you
can have a think about this if you're considering "localisation" one day
Paul

Tony Proctor

<PaulB> wrote in message news:tv1t61hng52rps6sa34s07ssr1drmol5o8@
4ax.com...
> Thank you for your comments, but now I'm scared.
>
> I'm wondering then if there is a Logic-SNAFU in my expectations then. I

really don't want to get to hour-650 and find
> out that I've had a lot of fun but need to address a fundamental

brain-fart embedded in my thinking...
> ( Like forgetting all about how useful account numbers might have been,

were they there )
>
>
> This is a "foundation" of what I am trying to do:
>
> Text-Type fields of the table is stored in an encoded form, encoded

meaning a simple character substitution thing.
> That's easy because there are sENCRYPT and sDECRYPT functions.
>
> However.... myString could be NULL
>
> I get killed with all of these expressions. It seems as if "myString"

can't even be used as a parameter if the thing is
> NULL
>
> textBox.text= sDECRYPT( myString, Len(myString) )
>
> textBox.text= sDECRYPT( myString, IIF( myString=NULL, 0, Len(

myString) ) )
>
> textBox.text= sDECRYPT( myString, IIF( IsNull(rsData1!Wage), 0,

Len(rsData1!Wage) ) )
>
> How do I refer to a NULL, and perhaps... "why" does it exist?
> Thanks,
>
> Paul
> ( This darn program refuses to do what I want
> it to. It ONLY does what I tell it to...
> and reluctantly. Remainds me of Bart Simpson )



Karl E. Peterson

2005-04-27, 3:55 pm

J French wrote:
>
> It kind of figures that it starts life like that
> - as zapping the stack is the most efficient way of initializing
> variables to 'nothing'
>
> However it is a bit disturbing that a zero length string can be either
> a vbNullString or a pointer to a zero length string


But it isn't yet a zero-length string, at that point, is it? There's gotta be some
hellacious checking going on on every reference, to insure that it gets initialized
properly when needed. That's what I don't like. Were strings objects, it seems not
unlike what would be required with a declaration like this:

Dim S As New String

> Not that it matters a jot within VB, but there are plenty of
> ramifications in the APIs
> - are you feeling queezy - I certainly am


Not yet, but I feel I may. <g> Wouldn't the instantiation check I describe above
deal with that?

> Personally I reckon they should have stuck with "" really being Null
> - it does not look as if a string's memory is reused if its length is
> reduced
> - perhaps they were aiming to retro-fit that later
> - they certainly re-use memory blocks for Arrays


What convinces you the memory isn't reclaimed?
--
Working Without a .NET?
http://classicvb.org/petition


Jim Mack

2005-04-27, 8:55 pm

Karl E. Peterson wrote:[color=darkred]
> J French wrote:
>
> But it isn't yet a zero-length string, at that point, is it? There's
> gotta be some
> hellacious checking going on on every reference, to insure that it
> gets initialized
> properly when needed. That's what I don't like. Were strings
> objects, it seems not
> unlike what would be required with a declaration like this:
>
> Dim S As New String
>

From the perspective of a library writer, there's an interesting twist.

If you have a function with an ODL interface that defines a parameter of
BSTR, and the caller passes either vbNullString _or_ "", you get exactly
the same thing: a valid BSTR with a length of 0. There's no need to
check for a null pointer, because you never get one.

VB apparently coerces the null pointer into a null string because the
interface description tells it that's what's needed. I'm pretty sure
you don't get the same help when using the Declare interface, but it's
been long enough that I don't remember.

--
Jim


Karl E. Peterson

2005-04-27, 8:55 pm

Hi Jim --

>
> From the perspective of a library writer, there's an interesting
> twist.
>
> If you have a function with an ODL interface that defines a parameter
> of BSTR, and the caller passes either vbNullString _or_ "", you get
> exactly the same thing: a valid BSTR with a length of 0. There's no
> need to check for a null pointer, because you never get one.


Wow, no kidding, huh? I guess you'd almost have to. ETC at work.

> VB apparently coerces the null pointer into a null string because the
> interface description tells it that's what's needed. I'm pretty sure
> you don't get the same help when using the Declare interface, but it's
> been long enough that I don't remember.


Definitely not with Declare, he says with utmost confidence. <G> You pass a
vbNullString in a parameter declared As String, and that's what's sent. Heh, that
always did make me uneasy, though, now that you mention it. I'd tend to define As
Any and pass ByVal 0&. There's something about being extremely explicit that has
paid off over the years...
--
Working Without a .NET?
http://classicvb.org/petition


J French

2005-04-28, 3:56 am

On Wed, 27 Apr 2005 09:53:38 -0700, "Karl E. Peterson" <karl@mvps.org>
wrote:

<snip>

[color=darkred]
>But it isn't yet a zero-length string, at that point, is it? There's gotta be some
>hellacious checking going on on every reference, to insure that it gets initialized
>properly when needed. That's what I don't like. Were strings objects, it seems not
>unlike what would be required with a declaration like this:


As it happens - I've just run up a test

' Test Sending uninitialized String
Private Sub Command6_Click()
Dim S1$, S2$

S2$ = ""
Call TestNullStr(S1$, S2$)
End Sub

// Delphi
Procedure TestNullStr( Var pS1, pS2:Integer );StdCall;
Begin
ShowMessage( IntToStr( pS1 ) + ' ' + IntToStr( pS2 ));
End;

Guess what - pS1 = 0 and pS2 is a memory location

> Dim S As New String


[color=darkred]
>Not yet, but I feel I may. <g> Wouldn't the instantiation check I describe above
>deal with that?


It would - but it ain't there

[color=darkred]
>What convinces you the memory isn't reclaimed?


I did a few tests checking StrPtr when resizing a String /down/
- StrPtr danced all over the place

Interestingly with Arrays, the VarPtr remains static if you Redim
Preserve them down and then back up

Private Sub Command1_Click()
Dim A&()

ReDim A&(1000)
Me.Print VarPtr(A&(1000))

ReDim Preserve A&(100)
Me.Print UBound(A())

ReDim Preserve A&(1000)
Me.Print VarPtr(A&(1000))

End Sub

However the same does not seem to happen for /simple/ Strings
- which surprizes me
There does seem to be an element of re-use ... but ...

Private Sub Command2_Click()
Dim S$, P&(3)

S$ = Space$(10)
P(1) = StrPtr(S$)

S$ = Space$(9)
P(2) = StrPtr(S$)

S$ = Space$(8)
P(3) = StrPtr(S$)

Me.Print P(1), P(2), P(3)
End Sub

I think that the moral is to be /very/ careful sending strings to APIs

Karl E. Peterson

2005-04-28, 3:57 pm

J French wrote:
>
>
> As it happens - I've just run up a test
>
> ' Test Sending uninitialized String
> Private Sub Command6_Click()
> Dim S1$, S2$
>
> S2$ = ""
> Call TestNullStr(S1$, S2$)
> End Sub
>
> // Delphi
> Procedure TestNullStr( Var pS1, pS2:Integer );StdCall;
> Begin
> ShowMessage( IntToStr( pS1 ) + ' ' + IntToStr( pS2 ));
> End;
>
> Guess what - pS1 = 0 and pS2 is a memory location


Okay, that's mildly disconcerting, alright...

>
>
>
> It would - but it ain't there


Ugh.

>
>
> I did a few tests checking StrPtr when resizing a String /down/
> - StrPtr danced all over the place


I seem to recall that anytime you change the length of a String, up or down, it's
actually reallocated and its content copied to the new buffer. MSBasic has had a
garbage collection process in place for decades, where this unallocated space is
occassionally reclaimed, though. That's the party line, anyway. <g>

> Interestingly with Arrays, the VarPtr remains static if you Redim
> Preserve them down and then back up
>
> Private Sub Command1_Click()
> Dim A&()
>
> ReDim A&(1000)
> Me.Print VarPtr(A&(1000))
>
> ReDim Preserve A&(100)
> Me.Print UBound(A())
>
> ReDim Preserve A&(1000)
> Me.Print VarPtr(A&(1000))
>
> End Sub
>
> However the same does not seem to happen for /simple/ Strings
> - which surprizes me
> There does seem to be an element of re-use ... but ...
>
> Private Sub Command2_Click()
> Dim S$, P&(3)
>
> S$ = Space$(10)
> P(1) = StrPtr(S$)
>
> S$ = Space$(9)
> P(2) = StrPtr(S$)
>
> S$ = Space$(8)
> P(3) = StrPtr(S$)
>
> Me.Print P(1), P(2), P(3)
> End Sub
>
> I think that the moral is to be /very/ careful sending strings to APIs


Yes.
--
Working Without a .NET?
http://classicvb.org/petition


J French

2005-04-29, 3:56 am

On Thu, 28 Apr 2005 10:46:37 -0700, "Karl E. Peterson" <karl@mvps.org>
wrote:

<snip>

[color=darkred]
>I seem to recall that anytime you change the length of a String, up or down, it's
>actually reallocated and its content copied to the new buffer. MSBasic has had a
>garbage collection process in place for decades, where this unallocated space is
>occassionally reclaimed, though. That's the party line, anyway. <g>


My understanding is that the old string space with garbage collection
approach was discarded - I don't know when.

In the old days a string was [ len ] [ ptr ->] and the actual string
was elsewhere with a back pointer
- the actual string would be moved by garbage collection - Fre( "" )
- the back pointer would update [ ptr -> ]

Now a string is just a pointer to the string's data which is preceded
by its length - so the 'string' does not move in memory

My understanding is that memory management is now really handled by
the CPU although I would expect VB to manage 'heaps'

I don't think that there is any garbage collection nowadays
- although there is some form of memory re-use
I guess I should run up a few tests and prove that.


Jim Mack

2005-04-29, 3:56 am

J French wrote:
> On Thu, 28 Apr 2005 10:46:37 -0700, "Karl E. Peterson" <karl@mvps.org>
> wrote:
>
> <snip>
>
>
>
> My understanding is that the old string space with garbage collection
> approach was discarded - I don't know when.
>
> In the old days a string was [ len ] [ ptr ->] and the actual string
> was elsewhere with a back pointer
> - the actual string would be moved by garbage collection - Fre( "" )
> - the back pointer would update [ ptr -> ]
>
> Now a string is just a pointer to the string's data which is preceded
> by its length - so the 'string' does not move in memory
>
> My understanding is that memory management is now really handled by
> the CPU although I would expect VB to manage 'heaps'
>
> I don't think that there is any garbage collection nowadays
> - although there is some form of memory re-use
> I guess I should run up a few tests and prove that.


My own reading of things is that there is GC, but that it's smarter than
the old-old methods used when Basic had 'Near string' and 'Far string'
memory models. For one thing, it isn't VB doing the managing, it's OLE.

Mind you, much of this is speculative and most of it is from
observation, not documentation.

An intervening model was the VB1-3 "HLSTR", which is a handle-based
scheme -- the 'string' you see is a true handle: an opaque identifier
that only the string manager can locate and manage. Handles are (or can
be) stable, unchanged for life even as the content grows or vanishes.
The same is not true for BSTR, which can move, seemingly at will.

The string manager creates an initial heap that it assumes will do, say
64K. This heap can grow, in largish increments. If the manager can't
fulfill an request for space, it will first compact, then grow the heap
if that isn't enough. I don't believe it will shrink the heap, once
grown.

It also uses the heuristic that strings created earlier in the program
tend to be the more stable ones -- and stable strings migrate to the
head of the heap. The goal is to move as little as possible, as rarely
as possible. But given the option, it will move a little bit, often,
rather than a lot, infrequently. There is a 'mini-GC' possible on every
string change.

String allocations are always done on DWORD boundaries, and string space
is always allocated in increments of 4 bytes. This small space
inefficiency pays off in more efficient heap shuffling.

When you do tests, also try the case where you are not always changing
the same string, since one modern optimization is to 'special-case'
access to recent and temporary strings, to avoid heap shuffling. Throw
a bunch of stuff in the pot.

--
Jim



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com