Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing an array with a negative number!

I am converting an extremely large and very old (25 years!) program from C to C++.

In it there are many (very very many) places where I access a global one dimensional UBYTE array using a variety of integer indexes. Occasionally this index may be negative.

I sometimes, but not always, trapped this case and made sure nothing went wrong, but as a belt and braces measure I actually went to the trouble of making sure that there was another chunk of memory immediately preceding the array and filled it with the right values such that if I accidentally omitted to trap the negative number condition then a correct answer would still be fetched in the array access. This actually worked fine for many many years.

But now under C++ it seems that accessing an array with a negative number behaves differently and now I have a program behaving badly. I fixed one case of an unhandled negative number and the program appears to be working fine, but I am nervous that I have not trapped all the negative numbers and there may be problems ahead.

So my question now is, is there a way, at runtime, for me to detect any instances of accessing arrays with negative indexes? I'll be impressed if anyone can come up with an answer. If you're pretty certain it can not be done in any automated way then telling me that is valuable information too.

I should just add that I'm not really a C++ programmer (yet). So far all I've done is the absolute bare minimum (almost nothing) to get the program to compile under a C++ compiler. So if your answer involves fancy "experts only, C++ solutions", then please try and explain in words of one syllable or give me a link so I can look it up.

like image 632
Mick Avatar asked Sep 14 '09 11:09

Mick


2 Answers

Can you replace the global one-dimensional ubyte array with an object with overloaded operator[]? Using the absolute value of the int input might solve some of your issues.

Edit: Depending on the usage pattern of your array (no pointer shenanigans), using an object with overloaded operator[] could actually be entirely transparent to the users of the array, hence my suggestion.

like image 151
Joris Timmermans Avatar answered Sep 29 '22 13:09

Joris Timmermans


Do you know the bounds of the indices?

Reading the comment under Siyfion's answer, it seems like negative indices are allowed in your problem domain, and so there's no point in trying to force all indices to be positive. A better solution is to allow negative indices without breaking any language rules (which your C version also did btw. You were just lucky it didn't explode ;))

So if you know that the indices you're going to use are in the range -x to y, simply create an array of size x+y, and use a pointer to the xth element when accessing the array.

For example, assuming you need an array with indices -4 to 5:

int arr[10];
int* ptr = arr+4;
// use ptr when you need to index into the array:

ptr[-4]; // is valid, reads arr[0]
ptr[5]; // is valid, reads arr[9]

Of course the same could (and should) have been done in C.

Another piece of advice would be to not access the raw array directly. Define simple accessor functions instead. (for example, but not necessarily, by putting the array in a class. If you do put it in a class, you can overload operator[] so it'll even look like an array still)

The overhead of this is precisely zero (not "nearly zero, or "so close to zero you won't notice the difference", but zero. The generated code will be exactly the same as if you'd accessed the array directly), as the compiler will inline short functions, but it also allows you to insert extra checks so that you can verify in debug builds that you never go past the bounds of the array.

like image 28
jalf Avatar answered Sep 29 '22 13:09

jalf