What happens when wrong indexes are used in c++2-d arrays?

HI everyone! I am a beginner of c++ and was doing an array program.I have entered the following code:

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
  #include <iostream.h>
  #include <conio.h>
  #include <stdio.h>

int main()
{
     clrscr();
     int sales[3][6];
     int i,j,total;
     
      for(i=1;i<=3;++i)
      { total=0;
        cout<<"enter sales for "<<i<<": \n";
      
         for(j=1;j<=6;j++)
        { cout<<" Month "<<j<<":";
          cin>>sales[i][j];
          total = total+sales[i][j];
          }
         cout<<"\n Total sales of salesman"<<i<<"="<<total<<"\n";
        }
         getch();
         return 0;
} 
          


The result is observed as:

Enter sales for 1:
Month 1:1
Month 2:1
Month 3:1
Month 4:1
Month 5:1
Month 6:1
Total sales of salesman1=6
enter sales for 2:
Month 1:1
Month 2:1
Month 3:1
Month 4:1
Month 5:1
Month 6:1
total sales of salesman2=2
enter sales for 3:
Month 1:1
Month 2:1
Month 3:1
Month 4:1
Month 5:1
Month 6:1
total sales of salesman3=6.

i know i have entered wrong array indexes and wrong inequality...Please check the total sales of salesman2 and the total sales of salesman 1 and salesman3.We find that the total is correct for 1 and 3 but not for salesman 2.I want to know why is that so? what's the cause behind it.Can you please help me. I have used turboc++ compiler.

thank you verymuch.
You're reading from and writing to memory locations that are outside that matrix. This causes undefined behavior. When the behavior of a program is undefined, literally anything can happen. The program may work correctly, it may compute incorrect results, it may crash, it may try to delete all your files, the computer may crash, etc. You just don't know. That's why you must always be careful to index arrays correctly.
Thank you very much sir, for your answer. I have understood that. But i am curious to know more deeper.Why is it only 2nd and why not 3.You see 3 is outside the matrix but sir still we get correct sollution.Why is that so? Can you please tell me
the arrays are mapped down to a 1-d block of memory. It is possible to put the wrong values in and get the correct answer; it can happen for example at (0,0) of course, and on a square array any (x,x) repeated value will work if reversed. You can also luck into the same value, if (3,2) and (2,3) happen to both be the same number. Honestly, this is the WORST thing that can happen, is getting the correct answer from the wrong code. It happens sometimes, and its one way bugs can sneak into code after testing.

Thank you sir but when i <=4 in the same program with Array sale[3][6] we get correct answer for salesman 1,3 and 4 leaving 2 again. You see..that the total only goes wrong for 2 and getting correct output for rest including outer matrices...
Last edited on
Like I said, the behavior is undefined. If you want to know at the immediate reason for why the program does what it does, you'll have to look at the disassembly. It's not possible to predict what a program with undefined behavior will do just by looking at the C++ code.
OK Thank you....
Hello Mite,

Although all good points I think they have missed the small point. Arrays start at an index of zero yet the for loops start at one. Which would make it very easy to exceed the top bound of the array.

Otherwise the program ran fine for me. I could not duplicate your problem yet.

Hope that helps,

Andy
Last edited on
The OP was not asking why the program doesn't work. They were asking why it does work sometimes.
Just to emphasize how deceitful could be looking for predictable results from undefined behaviour, I’ve modified Mike’s code to keep track of what happens at run time to the variable involved.
The result is totally machine-dependent and the output of the Windows machine is the one which can, perhaps, shed some light on the strange behaviour Mike pointed out.
Modified code:
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <cstdio>

int main()
{
    using std::cin;
    using std::cout;
    using std::endl;

    int sales[3][6];
    // Let's explore what's beyond our array limits
    cout << "\n\n\n\n";
    cout << "sales[3][6] ranges from 0 to 2 'rows' and 0 to 5 'columns'.\n" ;
    cout << "================================================" << endl;
    cout << "What's now at sales[3][1-5]:" << endl;
    for(int a(1); a<6; a++) {
        cout << "[3][" << a << "]=" << sales[3][a] << ";  ";
    }
    cout << endl;
    cout << "================================================" << endl;
    cout << "What's now at sales[1-3][6]:" << endl;
    for(int a(1); a<4; a++) {
        cout << "[" << a << "][6]=" 
        << sales[a][6] << ";  ";
    }
    cout << endl;
    cout << "================================================" << endl;

    unsigned long int address_sales, address_i, address_j;
    address_sales = (unsigned long)sales;
    bool onlyonce(true);
    // Let's stress our array now
    for(int i(1); i<4; i++) {
        address_i = (unsigned long)&i;
        int total(0);
        cout <<"\nEnter sales for " << i << ": \n";

        for(int j=1; j<7; j++) {
            address_j = (unsigned long)&j;
            if(onlyonce) {
                cout << "address of sales --> " << address_sales << endl;
                cout << "    address of i --> " << address_i << endl;
                cout << "    address of j --> " << address_j << endl;
                int distance = address_sales < address_i ? 
                            (address_i - address_sales) 
                            : (address_sales - address_i);
                cout << "distance between address of sales and i --> " 
                        << distance << endl;
                distance = address_sales < address_j ? 
                            (address_j - address_sales) 
                            : (address_sales - address_j);
                cout << "distance between address of sales and j --> " 
                        << distance << endl;
                onlyonce = false;
            }
            unsigned long next_used_address = (unsigned long)&sales[i][j];
            unsigned long lowerbound = next_used_address - sizeof(int) - 1;
            unsigned long upperbound = next_used_address + sizeof(int) + 1;
            if( (lowerbound < address_i && address_i < upperbound) ||
                (lowerbound < address_j && address_j < upperbound) )
                cout << "next input will interfere with some variable\n";
            cout << "sales[" << i << "][" << j << "] - " 
                    << next_used_address << " -"
                    <<" Month " << j <<": ";
            cin >> sales[i][j];
            total += sales[i][j];
        }
        cout <<"\ntotal sales of salesman " << i << " = " << total << endl;
    }
    getchar();
    return 0;
}


Windows 7 output (MinGw):
sales[3][6] ranges from 0 to 2 'rows' and 0 to 5 'columns'.
================================================
What's now at sales[3][1-5]:
[3][1]=-850091168;  [3][2]=0;  [3][3]=0;  [3][4]=0;  [3][5]=4202240;
================================================
What's now at sales[1-3][6]:
[1][6]=1974051906;  [2][6]=1974079842;  [3][6]=2686704;
================================================

Enter sales for 1:
address of sales --> 2686628
    address of i --> 2686704
    address of j --> 2686700
distance between address of sales and i --> 76
distance between address of sales and j --> 72
sales[1][1] - 2686656 - Month 1: 2
sales[1][2] - 2686660 - Month 2: 2
sales[1][3] - 2686664 - Month 3: 2
sales[1][4] - 2686668 - Month 4: 2
sales[1][5] - 2686672 - Month 5: 2
sales[1][6] - 2686676 - Month 6: 2

total sales of salesman 1 = 12

Enter sales for 2:
sales[2][1] - 2686680 - Month 1: 2
sales[2][2] - 2686684 - Month 2: 2
sales[2][3] - 2686688 - Month 3: 2
sales[2][4] - 2686692 - Month 4: 2
next input will interfere with some variable
sales[2][5] - 2686696 - Month 5: 2
next input will interfere with some variable
sales[2][6] - 2686700 - Month 6: 2
sales[2][3] - 2686688 - Month 3: 2
sales[2][4] - 2686692 - Month 4:


Linux output (GNU C++ compiler):
sales[3][6] ranges from 0 to 2 'rows' and 0 to 5 'columns'.
================================================
What's now at sales[3][1-5]:
[3][1]=397996653;  [3][2]=4198576;  [3][3]=0;  [3][4]=0;  [3][5]=0;  
================================================
What's now at sales[1-3][6]:
[1][6]=2;  [2][6]=881236480;  [3][6]=4196656;  
================================================

Enter sales for 1: 
address of sales --> 140723193953904
    address of i --> 140723193953832
    address of j --> 140723193953836
distance between address of sales and i --> 72
distance between address of sales and j --> 68
sales[1][1] - 140723193953932 - Month 1: 2
sales[1][2] - 140723193953936 - Month 2: 2
sales[1][3] - 140723193953940 - Month 3: 2
sales[1][4] - 140723193953944 - Month 4: 2
sales[1][5] - 140723193953948 - Month 5: 2
sales[1][6] - 140723193953952 - Month 6: 2

total sales of salesman 1 = 12

Enter sales for 2: 
sales[2][1] - 140723193953956 - Month 1: 2
sales[2][2] - 140723193953960 - Month 2: 2
sales[2][3] - 140723193953964 - Month 3: 2
sales[2][4] - 140723193953968 - Month 4: 2
sales[2][5] - 140723193953972 - Month 5: 2
sales[2][6] - 140723193953976 - Month 6: 2

total sales of salesman 2 = 12

Enter sales for 3: 
sales[3][1] - 140723193953980 - Month 1: 2
sales[3][2] - 140723193953984 - Month 2: 2
sales[3][3] - 140723193953988 - Month 3: 2
sales[3][4] - 140723193953992 - Month 4: 2
sales[3][5] - 140723193953996 - Month 5: 2
sales[3][6] - 140723193954000 - Month 6: 2

total sales of salesman 3 = 12
*** stack smashing detected ***: ./test.exe terminated
Annullato (core dump creato)

Thanks very much everyone for their support and answer.
Topic archived. No new replies allowed.