Are negative index in array allowed?

Are negative indexes allowed in c++?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 #include<iostream>
using namespace std;
int main()
 {
	
	int t,m,n,i,j;
	
	   cin>>m>>n;
	
	   int T[m][n];
	   
	   for(i=-1;i<m;i++)
	       {for(j=-1;j<n;j++)
	           {
	            T[i][j]=0;
	            cout<<"T["<<i<<"]["<<j<<"]="<<T[i][j]<<" ";
	           }
                 cout<<endl<<endl;
	           }
	       
	   
	   
	   	   
	   for(i=-1;i<m;i++)
	       {
	       for(j=-1;j<n;j++)
	           {
	               //cout<<T[i][j]<<" ";
	               cout<<"T["<<i<<"]["<<j<<"]="<<T[i][j]<<" ";
	           }
	           cout<<endl;
	       }   
	       
	   
	   
	 
	return 0;
}  



output-
T[-1][-1]=0 T[-1][0]=0 T[-1][1]=0 T[-1][2]=0 T[-1][3]=0 T[-1][4]=0 T[-1][5]=0

T[0][-1]=0 T[0][0]=0 T[0][1]=0 T[0][2]=0 T[0][3]=0 T[0][4]=0 T[0][5]=0

T[1][-1]=0 T[1][0]=0 T[1][1]=0 T[1][2]=0 T[1][3]=0 T[1][4]=0 T[1][5]=0

T[2][-1]=0 T[2][0]=0 T[2][1]=0 T[2][2]=0 T[2][3]=0 T[2][4]=0 T[2][5]=0

T[3][-1]=0 T[3][0]=0 T[3][1]=0 T[3][2]=0 T[3][3]=0 T[3][4]=0 T[3][5]=0

T[4][-1]=0 T[4][0]=0 T[4][1]=0 T[4][2]=0 T[4][3]=0 T[4][4]=0 T[4][5]=0

T[-1][-1]=0 T[-1][0]=24 T[-1][1]=0 T[-1][2]=-1185892592 T[-1][3]=32764 T[-1][4]=4197545 T[-1][5]=0
T[0][-1]=0 T[0][0]=0 T[0][1]=0 T[0][2]=0 T[0][3]=0 T[0][4]=0 T[0][5]=0
T[1][-1]=0 T[1][0]=0 T[1][1]=0 T[1][2]=0 T[1][3]=0 T[1][4]=0 T[1][5]=0
T[2][-1]=0 T[2][0]=0 T[2][1]=0 T[2][2]=0 T[2][3]=0 T[2][4]=0 T[2][5]=0
T[3][-1]=0 T[3][0]=0 T[3][1]=0 T[3][2]=0 T[3][3]=0 T[3][4]=0 T[3][5]=0
T[4][-1]=0 T[4][0]=0 T[4][1]=0 T[4][2]=0 T[4][3]=0 T[4][4]=0 T[4][5]=0

why different values are getting printed for T[-1][2], T[-1][3], T[-1][4]
First of all, this is not allowed in C++:
1
2
	   cin>>m>>n;
	   int T[m][n];

you seem to be using one of the compilers (specifically, gcc or clang) that has a non-portable language extension that allows this kind of non-C++ arrays. Make sure to compile with -pedantic-errors to use portable C++, otherwise it may be difficult to discuss your code with others.

As for negative indexes, they compile, but if the resulting location is outside the array (it is in your case), the behavior of the program is undefined. It can do anything at all, including giving you any sort of output, crashing, mysteriously skipping chunks of code, etc. Many classes of errors in C++ (and in C) behave that way.
ok, but how can I get printed correct values here?
T[-1][0] and all other T[-1][n] do not exist, what would their "correct values" be?
ok, thanks!!
you can use negative indices and they can be handy.

Lets take a bucket sort to sort numbers from -10 to 10.

how about this...

int basebucket[21] = {0}; //standard layout {0,1,2,3,...20}
int *bucket = &(basebucket[11]); moved layout {-10, -9, -8, ... 0(bucket) ... 10}

now you can sort a list of values in the given range (-10 to 10) with the simple
for(... list)
bucket[number]++;

granted, its a really simple example, and as a side note this kind of thing is 'fragile' code (easy to break it, and bug prone if careless). Vectors would take a lot more effort to get this sort of functionality, but you can do it. Given that pointers and arrays are of limited value in modern code, this kind of hack becomes dubious and off in the realm of "you really should have a very, very good reason to go here".

Note that you can't just use negative index without allocating memory on both sides of the 'zero offset' somehow -- the above "pointer in the middle" approach being the most common way to do that.


Last edited on
c++ doesnt have bounds checking so when you do negative index i believe you are accessing the memory sequentially located in front of the array in memory. That can be anything and is usually not something you want
that is exactly what it does. Useless for arrays, but fine for pointers that are indexed as an array, if set up for the technique.
jonnin,

Ignoring whether or not your example is considered fragile, the bad thing is that it would only work on raw arrays, you'd have to do hackish things like .data() to get it to work with modern C++ vectors. Just saying.
Probably is more maintainable to just have a known offset/index mapping instead of working with pointer arithmetic!
Yes, that is why I said it had limited value in modern code (pretty much true for all array and pointer hacks).

You can make it work with a static (fixed size) vector, I don't think that would be too hard. Worst case you could just overload a [] operator to fudge the index for you. There is probably an iterator hack for it, but I will admit to that being beyond my ability to write in a 10 second post here -- I struggle with iterators beyond the most simple uses.

Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;

template <typename T> class ARRAY
{
   int lower, upper;
   T *a;

public:
   ARRAY( int m, int n ) : lower( m ), upper( n ) { a = new T[n-m+1]; }
   ~ARRAY() { delete [] a; }

   T &operator[]( int i )
   { 
      if ( i < lower || i > upper )
      { 
         cout << "Outside array bounds"; 
         exit( 1 );
      }
      else 
      {
         return a[i-lower];
      }
   }
};


//======================================================================


int main()
{
   ARRAY<int> T(-10,10);
   int i;

   for ( i = -10; i <= 10; i++ ) T[i] = 100 * i;

   for ( i = -10; i <= 10; i++ ) cout << setw( 3 ) << i << "  " << setw( 5 ) << T[i] << '\n';

   while ( true )
   {
      cout << "Input an index: ";
      cin >> i;
      cout << "T[" << i << "]=" << T[i] << "\n\n";
   }
}


//====================================================================== 

-10  -1000
 -9   -900
 -8   -800
 -7   -700
 -6   -600
 -5   -500
 -4   -400
 -3   -300
 -2   -200
 -1   -100
  0      0
  1    100
  2    200
  3    300
  4    400
  5    500
  6    600
  7    700
  8    800
  9    900
 10   1000
Input an index: 3
T[3]=300

Input an index: -6
T[-6]=-600

Input an index: -10
T[-10]=-1000

Input an index: -11
Outside array bounds
Last edited on
missing copy constructor and assignment operator
`lower' and `upper' may be template parameters
1
2
3
template <class T, int lower, int upper> class array{
   T data[upper-lower+1];
};
Topic archived. No new replies allowed.