Are negative index in array allowed?

Aug 23, 2017 at 5:14pm
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]
Aug 23, 2017 at 5:25pm
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.
Aug 23, 2017 at 5:35pm
ok, but how can I get printed correct values here?
Aug 23, 2017 at 6:38pm
T[-1][0] and all other T[-1][n] do not exist, what would their "correct values" be?
Aug 23, 2017 at 7:00pm
ok, thanks!!
Aug 23, 2017 at 8:02pm
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 Aug 23, 2017 at 8:03pm
Aug 23, 2017 at 9:10pm
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
Aug 24, 2017 at 5:59pm
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.
Aug 24, 2017 at 7:28pm
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!
Aug 24, 2017 at 8:58pm
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 Aug 24, 2017 at 8:59pm
Aug 24, 2017 at 9:16pm
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 Aug 24, 2017 at 9:27pm
Aug 25, 2017 at 12:39am
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.