Board index » delphi » Very strange range checking bug

Very strange range checking bug

Ok, now this one I *definately* don't understand - I cannot
fathom ANY way that this error could occur:

in my code I have:

var
   Check: array[1..4] of integer;
   numFound, counter, current:integer;
   found:boolean;
begin

...

if numFound > 0 then
begin
     for counter:=0 to numFound do
     begin
          showmessage(inttostr(counter));
          if current = check[counter] then found:=true;
     end;
end;

This code works fine, I've never had a problem with it.  But when
I turned on Range Checking this morning to discover the problem I
was having elsewhere, I just got an error on this code.

It crashes with a range check error on the 'if current...' line
and when I hover the mouse over things I see that counter is '-1'
or '2465465454' or whatever it feels like being at the time, yet
during execution it is fine - ie the messagebox I ask for comes
up with '0', numfound at this stage is 1 btw, like it should be,
check has been defined - it's currently [3,0,0,0], and current is
4, but that's all irrelevant...

What could possibly cause this problem?  I can easily enough turn
off range checking again, but I'm curious...

Regards

OgO
--
My Freeware: http://qjc.cjb.net/freeware.html
My Win9x Cursors: http://qjc.cjb.net/cursors.html
ICQ: 12889482 - AIM/Yahoo: quentisl - MSN: quent...@mail.com
I left my Glasses in my email - you better take them out!

 

Re:Very strange range checking bug


Quote
"OgO" <quent...@qjc.cjbGlasses.net> wrote in message

news:Xns92488B517FC06ogo1mynxwowaustcom@210.49.20.254...

Quote
> Ok, now this one I *definately* don't understand - I cannot
> fathom ANY way that this error could occur:
>var
>   Check: array[1..4] of integer;
>   numFound, counter, current:integer;
>   found:boolean;
>...
>      for counter:=0 to numFound do
>      begin
>           showmessage(inttostr(counter));
>           if current = check[counter] then found:=true;
>      end;
> end;

check[0] finds something, probably the pointer
to the utility string used to hold result from inttostr

this is almost guaranteed not to match any of your
potential 'current' values, so will usually proceed to check[1]
numfound will limit your check array max

with arrays usually  you index by either
  start at 1 and go to array size
or
  start at 0 and go to arraysize-1

Re:Very strange range checking bug


In comp.lang.pascal.delphi.misc, on 11 Jul 2002, Terry
Russell announced:

Quote
> check[0] finds something, probably the pointer
> to the utility string used to hold result from inttostr

> this is almost guaranteed not to match any of your
> potential 'current' values, so will usually proceed to
> check[1] numfound will limit your check array max

> with arrays usually  you index by either
>   start at 1 and go to array size
> or
>   start at 0 and go to arraysize-1

Yup, I always try to start at 0 and go to arraysize-1 since
arrays are indexed from 0, if I want an array of size n, and make
a new array of size n it's going to be indexed from 0 to n-1
anyway.  I made sure I got that one right (that time at least ;).

Strange, I'd turned the range checking detection off so it would
run properly while I did other stuff, and now I turned it back on
to have another play with it - and it no longer comes up with an
error....  I haven't touched that part of the code (except to
remove that showmessage call which I only put in there when I
started getting the error....)

Maybe it's a 'Borland using all the memory and coming up with
silly errors which don't really exist' type problem, rather than
an 'I've left a semi-colon off somewhere' type problem...

Regards

OgO
--
My Freeware: http://qjc.cjb.net/freeware.html
My Win9x Cursors: http://qjc.cjb.net/cursors.html
ICQ: 12889482 - AIM/Yahoo: quentisl - MSN: quent...@mail.com
I left my Glasses in my email - you better take them out!

Re:Very strange range checking bug


Quote
"OgO" <quent...@qjc.cjbGlasses.net> wrote in message
> var
>    Check: array[1..4] of integer;
>    numFound, counter, current:integer;
>    found:boolean;
> begin

> ...

> if numFound > 0 then
> begin
>      for counter:=0 to numFound do
>      begin
>           showmessage(inttostr(counter));
>           if current = check[counter] then found:=true;
>      end;
> end;

Once an exception is raised, debug cannot accurately display the value of
the index variable. If you want to know what it is you need to put in a
breakpoint and check each iteration.

IMO its a poor idea to have the loop start at zero. It will certainly cause
a bounds check error, since Low (Check) = 1. I tend to use Low and High
whenever possible in loops. It makes the code independent of changes in the
array bounds and is thus, IMO, more robust.

    for counter := Low (Check) to (Low (Check) + numFound) do

The code snippet didn't show any check on numFount being too large.

I take it the code snippet is searching for the first match, if any. I'd be
inclined to write it

    counter := Low (Check);
    repeat
        found := current = Check (counter);
    until found or (counter > (Low (Check) + numFound));

Although for 4 entries it doesn't make a great deal of difference.

Re:Very strange range checking bug


In comp.lang.pascal.delphi.misc, on 11 Jul 2002, Bruce
Roberts announced:

Quote
> Once an exception is raised, debug cannot accurately
> display the value of the index variable. If you want to
> know what it is you need to put in a breakpoint and check
> each iteration.

Ok, that explains why counter was coming up with strange values,
although it does make checking things harder if you have a range
check error caused by a counter whose value delphi won't tell
you!

Quote
> IMO its a poor idea to have the loop start at zero. It will
> certainly cause a bounds check error, since Low (Check) =
> 1. I tend to use Low and High whenever possible in loops.
> It makes the code independent of changes in the array
> bounds and is thus, IMO, more robust.

since when are arrays 1-based?  If I don't know what the array is
starting at, how can I reference the right element of the array!

Particularly when, for instance I don't just want to loop through
doing something with each element, but *know* I want myArray[2]
or whatever....  I should use myArray[low(myArray)+2] instead?  
That seems such a silly way of doing it.... and much harder to
read...

Regards

OgO
--
My Freeware: http://qjc.cjb.net/freeware.html
My Win9x Cursors: http://qjc.cjb.net/cursors.html
ICQ: 12889482 - AIM/Yahoo: quentisl - MSN: quent...@mail.com
I left my Glasses in my email - you better take them out!

Re:Very strange range checking bug


Hi,

When range-check is ON, you get an error because you have 'Check[0]'
which is against the definition of ;Check: array[1..4]'...

When range-check is OFF, Delphi does not care - so when 'Check[0]'
happens, instead of raising an exception, Delphi simply goes out of
the boundary of your array in memory and gives you back whatever is
there (hence the strange values you are getting).

Cheers

Quote
OgO <quent...@qjc.cjbGlasses.net> wrote in message <news:Xns92488B517FC06ogo1mynxwowaustcom@210.49.20.254>...
> Ok, now this one I *definately* don't understand - I cannot
> fathom ANY way that this error could occur:

> in my code I have:

> var
>    Check: array[1..4] of integer;
>    numFound, counter, current:integer;
>    found:boolean;
> begin

> ...

> if numFound > 0 then
> begin
>      for counter:=0 to numFound do
>      begin
>           showmessage(inttostr(counter));
>           if current = check[counter] then found:=true;
>      end;
> end;

> This code works fine, I've never had a problem with it.  But when
> I turned on Range Checking this morning to discover the problem I
> was having elsewhere, I just got an error on this code.

> It crashes with a range check error on the 'if current...' line
> and when I hover the mouse over things I see that counter is '-1'
> or '2465465454' or whatever it feels like being at the time, yet
> during execution it is fine - ie the messagebox I ask for comes
> up with '0', numfound at this stage is 1 btw, like it should be,
> check has been defined - it's currently [3,0,0,0], and current is
> 4, but that's all irrelevant...

> What could possibly cause this problem?  I can easily enough turn
> off range checking again, but I'm curious...

> Regards

> OgO

Re:Very strange range checking bug


On 11 Jul 2002 06:39:52 GMT, OgO <quent...@qjc.cjbGlasses.net> wrote:

Quote
>since when are arrays 1-based?

Since you declared it that way:

Quote
>var
>   Check: array[1..4] of integer;

The 1 in the line above is the lower limit, the 4 is the upper limit.

You're probably thinking of some other weird language where you don't
get a choice about the lower limit of the array, like "C" or
something.

Duncan Murdoch

Re:Very strange range checking bug


Quote
"OgO" <quent...@qjc.cjbGlasses.net> wrote in message
> since when are arrays 1-based?  If I don't know what the array is
> starting at, how can I reference the right element of the array!

Since you declared it to start at 1, as Duncan points out.

Quote
> Particularly when, for instance I don't just want to loop through
> doing something with each element, but *know* I want myArray[2]
> or whatever....  I should use myArray[low(myArray)+2] instead?
> That seems such a silly way of doing it.... and much harder to
> read...

It only seems silly until you run into the situation that your original post
raises. When I use arrays that I will be referencing with constant indexes I
tend to use much more descriptive indices, e.g. myArray [moJuly], or myArray
[Port2]. And in those situations I don't use Low. But, as I believe I stated
in my previous post the point is to use Low and High in loops. I don't
believe I said anything about other situations.

Re:Very strange range checking bug


On 11 Jul 2002 03:41:43 GMT, OgO <quent...@qjc.cjbGlasses.net> wrote:

Quote
> var
>    Check: array[1..4] of integer;
...
>      for counter:=0 to numFound do
>      begin
>           showmessage(inttostr(counter));
>           if current = check[counter] then found:=true;

Counter is 0, but the array is declared as array[1..4]. Of course that
index is out of range.

Re:Very strange range checking bug


On 11 Jul 2002 04:50:19 GMT, OgO <quent...@qjc.cjbGlasses.net> wrote:

Quote
> Yup, I always try to start at 0 and go to arraysize-1 since
> arrays are indexed from 0

They're not. The array[1..4] is indexed from 1 up to and including 4.

Most arrays currently start at 0, but this is not a requirement.

Re:Very strange range checking bug


In comp.lang.pascal.delphi.misc, on 11 Jul 2002, unko
announced:

Quote
> Hi,

> When range-check is ON, you get an error because you have
> 'Check[0]' which is against the definition of ;Check:
> array[1..4]'...

Aha, I've finally noticed it!

in order for my array to be zero based should I declare it as:

Check: array[0..3] of integer;

then instead?

I hadn't really thought about the first number before, I'd just
thought that arrays were zero based, they always are, they are in
C, they are in Delphi...

I'd just assumed (yes I know, ass out of you and me, well mostly
me...) that:

Check: array[1..4] of integer;

was the same as C's:

int Check[4];

the '4' being the important 'number of elements in the array'
number....

That then doesn't explain why it's stopped giving me the error
now, but ah well, I know how to fix it now, and more importantly,
the whole, arrays are not all zero based in delphi lesson :)

Regards

OgO
--
My Freeware: http://qjc.cjb.net/freeware.html
My Win9x Cursors: http://qjc.cjb.net/cursors.html
ICQ: 12889482 - AIM/Yahoo: quentisl - MSN: quent...@mail.com
I left my Glasses in my email - you better take them out!

Re:Very strange range checking bug


In comp.lang.pascal.delphi.misc, on 11 Jul 2002, Duncan
Murdoch announced:

Quote
> On 11 Jul 2002 06:39:52 GMT, OgO
> <quent...@qjc.cjbGlasses.net> wrote:

>>since when are arrays 1-based?

> Since you declared it that way:

Yes I just discovered that :)

Quote
>>var
>>   Check: array[1..4] of integer;

> The 1 in the line above is the lower limit, the 4 is the
> upper limit.

Yes, I never realised that arrays could be anything other than
zero based.... well I 'knew' it was theoretically possible, I'd
never come across it before.

Quote
> You're probably thinking of some other weird language where
> you don't get a choice about the lower limit of the array,
> like "C" or something.

I certianly was, but at least in such weird languages, the
structure of simple integer arrays isn't made so complex.... If
you start declaring arrays starting at any number it can only get
confusing and lead to problems such as my range checking error
which started this whole thread...

Ah well, I'll keep an eye out for that from now on.

Regards

OgO
--
My Freeware: http://qjc.cjb.net/freeware.html
My Win9x Cursors: http://qjc.cjb.net/cursors.html
ICQ: 12889482 - AIM/Yahoo: quentisl - MSN: quent...@mail.com
I left my Glasses in my email - you better take them out!

Re:Very strange range checking bug


In comp.lang.pascal.delphi.misc, on 12 Jul 2002, Bruce
Roberts announced:

Quote
>> Particularly when, for instance I don't just want to loop
>> through doing something with each element, but *know* I
>> want myArray[2] or whatever....  I should use
>> myArray[low(myArray)+2] instead? That seems such a silly
>> way of doing it.... and much harder to read...

> It only seems silly until you run into the situation that
> your original post raises.

Well what I meant by silly was that the way your post read to me
was that 'you should use low and high to reference array elements
because the actuall values of the array do not need to be known
to you, you shouldn't go called 'myArray[3]' for instance'.  I do
get what you mean now though.

The point of my original post was that believing that arrays are
zero based, myArray[0] CANNOT be out of bounds, which is what the
range check error was telling me, and in a zero based array
myArray[0] certainly can't be out of bounds - what I'd missed was
that my array wasn't zero based :)

I thought I knew what the upper and lower bounds of my array were
and I knew which elements I wanted to refernce.  But I get it now
:)

Regards

OgO
--
My Freeware: http://qjc.cjb.net/freeware.html
My Win9x Cursors: http://qjc.cjb.net/cursors.html
ICQ: 12889482 - AIM/Yahoo: quentisl - MSN: quent...@mail.com
I left my Glasses in my email - you better take them out!

Re:Very strange range checking bug


On 11 Jul 2002 23:41:08 GMT, OgO <quent...@qjc.cjbGlasses.net> wrote:

Quote
>In comp.lang.pascal.delphi.misc, on 11 Jul 2002, Duncan
>Murdoch announced:

>> You're probably thinking of some other weird language where
>> you don't get a choice about the lower limit of the array,
>> like "C" or something.

>I certianly was, but at least in such weird languages, the
>structure of simple integer arrays isn't made so complex....

I think C is the language that makes things strange.  If you declare
it as a:array[1..4] of integer, then a[1] .. a[4] are all allowed to
be referenced.  If you declare it in c as integer a[4], then a[4] is
*not* allowed.  Seems weird to me.

 If

Quote
>you start declaring arrays starting at any number it can only get
>confusing and lead to problems such as my range checking error
>which started this whole thread...

On the contrary, it's really useful in certain situations.  Say bytes
13 through 16 in a structure need to be accessed, and bytes 1 thru 12
are used in 3 integers.  Then it's really natural to declare the
structure as

  packed record
     i1,i2,i3 : integer;
     bytes : array[13..16] of byte;
  end;

I'd blame your error on C's weirdness, not on anything confusing in
Delphi.

Duncan Murdoch

Re:Very strange range checking bug


Quote
OgO wrote in message ...

[...]

Quote
>I hadn't really thought about the [low index] before, I'd just
>thought that arrays were zero based, they always are, they are in
>C, they are in Delphi...

>I'd just assumed (yes I know, ass out of you and me, well mostly
>me...) that:

>Check: array[1..4] of integer;

>was the same as C's:

>int Check[4];

>the '4' being the important 'number of elements in the array'
>number....

In answer to your question earlier "since when are arrays
one-based?": in Pascal, they have always been - by default.
(I just checked and Delphi requires a range. And yet, I
have this insistent memory that once upon a time, "array [n]
of type" was a valid declaration.)

C was designed to be simple, efficient, and close to the
machine. Pascal was designed to look friendly to people, and
sod the machine. Obviously, Wirth was a computer scientist
and no mathematician, or he might actually have designed array
indices to be integers modulo n. Or perhaps he was just being
"not C" and choosing the other viable option, or perhaps he
even asked his mother what she preferred. Because it does come
natural to most people to count from 1 to n.

Groetjes,
Maarten Wiltink

Go to page: [1] [2]

Other Threads