Quick question about arrays and odd behavior

M

Mike Cain

I have an odd situation I'm trying to understand..... I'm using MS VS 7.0
C++ with the MFC CBuffer class.

If I do this:

#define NUM_ELEMENTS 2
CBuffer<char, 512> x[NUM_ELEMENTS-1];
CBuffer<char, 512> y[NUM_ELEMENTS-1];

So as you can see I have two variables which will hold strings, each of
which has two elements. One at position [0] and the other at [1].

However with the above definition x[1] and y[0] point at the same exact
address and overwrite one another! Why is this??

If I define those vars as NUM_ELEMENTS, instead of NUM_ELEMENTS-1, then
things work great. It would think that [1] would do the trick since I have
[0] for the first element and [1] for the second. So why is it then
necessary to have these defined as [2]? And yes I am certain when I am
writing to these vars I'm using [0] to address the first element and [1] to
address the second.

Defining it as [NUM_ELEMENTS] seems to do the trick to resolve this issue,
but I wanted to better understand why I am seeing that behavior to make sure
that this apparent fix is not an illusion with a subtle bug waiting to bite
me!

Thanks!!
 
A

Alunduil

Mike said:
I have an odd situation I'm trying to understand..... I'm using MS VS 7.0
C++ with the MFC CBuffer class.

If I do this:

#define NUM_ELEMENTS 2
CBuffer<char, 512> x[NUM_ELEMENTS-1];
CBuffer<char, 512> y[NUM_ELEMENTS-1];

So as you can see I have two variables which will hold strings, each of
which has two elements. One at position [0] and the other at [1].

The way you have defined NUM_ELEMENTS and your arrays lead to them being only of
one cell each. Remove the -1, and you will have the behavior you described. This
is because when you initialize an array you are passing the number of elements
(i.e. the size). You are not declaring the highest index used by the array.

Regards,

alunduil
 
T

Thomas J. Gritzan

Mike said:
I have an odd situation I'm trying to understand..... I'm using MS VS 7.0
C++ with the MFC CBuffer class.

If I do this:

#define NUM_ELEMENTS 2
CBuffer<char, 512> x[NUM_ELEMENTS-1];
CBuffer<char, 512> y[NUM_ELEMENTS-1];

So as you can see I have two variables which will hold strings, each of
which has two elements. One at position [0] and the other at [1].

No.

In an array, you declare the *size* (number of elements) in brackets, which
you access with an zero-based index.

Example:

int arr[5];
// arr has 5 elements, from arr[0] to arr[4]

char s[1];
// s has exactly one element: s[0]
 
J

Jack Klein

I have an odd situation I'm trying to understand..... I'm using MS VS 7.0
C++ with the MFC CBuffer class.

If I do this:

#define NUM_ELEMENTS 2
CBuffer<char, 512> x[NUM_ELEMENTS-1];

When the preprocessor replaces the macro, the line above becomes:

CBuffer said:
CBuffer<char, 512> y[NUM_ELEMENTS-1];

When the preprocessor replaces the macro, the line above becomes:

CBuffer said:
So as you can see I have two variables which will hold strings, each of
which has two elements. One at position [0] and the other at [1].

So as I hope you can now see, you have two variables which will hold
strings, each of which has ONE element. There is no x[1] or y[1].
However with the above definition x[1] and y[0] point at the same exact
address and overwrite one another! Why is this??

Because x[1] does not exist, it is beyond the end of the array.
Attempting to access an element beyond the end of an array produces
undefined behavior. The result of that undefined behavior in this
particular case with your particular compiler happens to be that you
actually access y[0].
If I define those vars as NUM_ELEMENTS, instead of NUM_ELEMENTS-1, then
things work great. It would think that [1] would do the trick since I have
[0] for the first element and [1] for the second. So why is it then
necessary to have these defined as [2]? And yes I am certain when I am
writing to these vars I'm using [0] to address the first element and [1] to
address the second.

Defining it as [NUM_ELEMENTS] seems to do the trick to resolve this issue,
but I wanted to better understand why I am seeing that behavior to make sure
that this apparent fix is not an illusion with a subtle bug waiting to bite
me!

Apparently you are new to C++, as the use of array subscripts can be
mildly confusing at first. The good news is that once you understand
it, you will almost certainly never forget it.

The number that goes in the brackets when you DEFINE an array is the
total number of array elements that you want. The valid values for
subscripts to access elements of the array are from 0 to (total - 1),
inclusive.

That is:

type array [TOTAL];

....for any valid "type" that you can create an array of, and any
positive value of TOTAL, has elements:

array [0];
array [1];
/* ... */
array [TOTAL - 2];
array [TOTAL - 1];
/* no more */

So when define your arrays with NUM_ELEMENTS elements, where
NUM_ELEMENTS is a macro for 2, then you are indeed creating those
arrays with two elements, each one has a [0] element and a [1]
element.

So the "apparent fix" is actually correct, and your original code is
incorrect, based on a misunderstanding about the way subscripts are
used in array definition versus array element access.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top