Array - Last index - c++

In an array, the index of the first element is zero. So an array declared as:
int a[5];
should have a[4] as the last element. However, when I execute the following code:
int n;
cin>>n;
int a[n];
for(int i = 0; i++<n; cin>>a[i]);
for(int i = 0; i++<n; cout<<i<<" "<<a[i]<<endl);
And give the input as:
5 1 2 3 4 5
The output is:
1 1
2 2
3 3
4 4
5 5
That implies that a[5] = 5. I was wondering as to how that is possible. Shouldn't it display some garbage value instead?

change i++ < n to i < n and cin>>a[i] to cin>>a[i++]

Logical. You are doing it wrong. Consider corner where n = 5:
Your i is 4. You do check if i++ < 5 is true and after check, i increases.
I is now 5 and this is out of bounds.
Your loop actually runs from 1 to 5 instead of 0 to 4.
Rewrite codes to:
for (int i = 0; i < n; cin >> a[i], i++);
for (int i = 0; i < n; cout << i << " " << a[i] << endl, i++);

Shouldn't it display some garbage value instead?
Teaching that an unitialized variable has a garbage value or that accessing an array will yield garbage values is really a disservice.
Accessing an uninitialized variable or an array out of bounds in C++ is Undefined Behavior. This means that the program can behave in any way. It can crash, it can appear to function, it can any behavior, it can appear to have garbage values in unitialized variables.

Alternatively you could just replace
int i=0 by int i=-1 and,
i++ by ++i
Now the loop will run and enter the values from a[0] to a[4] as expected.
The code could be rewritten as:
for(int i=-1;++i<n;cin>>a[i]);
for(int i=-1;++i<n;cout<<i<<" "<<a[i]<<endl);

Related

What are all of these numbers following the expected output?

I was trying to write a program to take an input and output the reverse of that input; here was my code:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int num[n];
for (int i=1; i<=n; i++)
{
cin >> num[i];
}
for (int i=n; i>=0; i--)
{
cout << num[i] << " ";
}
return 0;
}
I realized that in the second for loop, i can equal 0 and then i equals -1. However, the outputs don't really make sense. For example, an input of
6
8 1 2 6 3 9
results in
9 3 6 2 1 8 8 8
and a lot of the time it's just the array reversed but with an 8 added onto the end, but sometimes there are these types of numbers:
9
1 0 2 8 1 4 2 9 8
8 9 2 4 1 8 2 0 1 1703936
Where do these ending numbers come from? Because I don't understand what's going on, I can't generalize what the problem is, but if you have an easily-accessible IDE nearby and will copy and paste my code (assuming it's not a well-known problem and I'm making everyone laugh at my stupidity), could anyone tell me why there are these numbers added onto the end?
for (int i=1; i<=n; i++)
In C++, array indexes are 0-indexed. This means if your array is size n, the valid indexes are 0, 1, 2, ..., n-1.
Your loop will loop over 1, 2, 3, ..., n. Do you see the issue? You never write to the 0'th index, and you write one past the last index (which is not allowed).
Then when you go to print:
for (int i=n; i>=0; i--)
You print n, n-1, n-2, ..., 0. You're printing the n'th element, which is again, not allowed.
Instead, your loops should look like:
for (int i=0; i<n; i++)
{
cin >> num[i];
}
for (int i = 0; i < n; i++)
{
cout << num[n - i - 1] << " ";
}
Your second loop begins with i equal to n ... but that's not a valid array index, because an array containing n elements has indexes [0..n-1]! Therefore, you are seeing "memory garbage."
So, your second loop should be:
for (int i=n-1; i>=0; i--)
You seem to think that arrays are indexed from 1 which is your main issue.
for (int i=1; i<=n; i++)
The last element of an array if length-1, so if you had 3 elements the last index is 2, not 3; however, the loop above starts at 1 (the second element) and then accesses an index out of bounds, which is undefined behaviour.
But really you don't need to use indices at all, just for (auto& i : n) will iterate properly over your container. If you want to loop using indices, you need
for (int i = 0; i < n; i++) // forwards
for (int i = n-1; i >= 0; i--) //backwards
It's worth noting that variable length arrays (that is, arrays whose lengths are not known at compile time) are not standard C++, but are an extension of GCC. It would be worth ditching that behaviour now, and using vector instead:
int length = 0;
std::cin >> length;
std::vector<int> n(length);

2D array elements not being read properly

The output is a string of numbers of entire row/column instead of a single number. Can someone please help me in this?
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int t;
cin>>t;
while(t--){
int n,m,cnt=0;
cin>>n>>m;
for(int i=0;i<=n+1;i++){
for(int j=0;j<=m+1;j++){
if(i==0||i==n+1||j==m+1||j==0) G[i][j]=0;
cin>>G[i][j];
}
}
cout<<G[1][2]<<endl;//this gives wrong o/p
return 0;
}
Most likely you are reading out of bounds due to a i <= n + 1 and j <= m + 1 conditions in your for loops thus invoking undefined behavior resulting in a corrupted stack which explains the output you are seeing. Modify the boundaries to:
i < n and j < m. Arrays are zero indexed in C++. First array element is accessed via somearray[0] and the last element is somearray[n-1] not somearray[n] which is what you are trying to access in your code. The same goes for multi-dimensional arrays. The statement of:
cout << G[i][j] << endl;
is wrongly placed outside the for loops. It should be inside the inner for loop. The array should be defined as a second statement in your while loop:
int G[n][m]; // Avoid VLAs
That being said variable length arrays are not part of the C++ standard and you should prefer std::vector and std::array to raw arrays.
Assuming G is a 2D array of size n x m, then you go out of bounds here:
for(int i=0;i<=n+1;i++) {
for(int j=0;j<=m+1;j++)
since array indexing starts from 0, and ends at size - 1.
As a result, your code invokes Undefined Behavior. To avoid that, simply change your double for loop to this:
for(int i = 0; i < n; i++) {
for(int j = 0;j < m; j++)

Array overflow c++ (at arr[0])?

Ok so last night I taught my sister some basic code how to read input, put it in array and print it to the screen. Here is the code :
int main() {
int N; // size of array
cin >> N;
int arr[N];
for(int i = 1; i<= N; i++) {
cin >> arr[i];
}
for(int i = 0; i<N; i++) {
cout << arr[i] << endl;
}
return 0;
}
And here is the result :
input :
4
2 3 4 1
output :
8
2
3
4
I don't have any clues why this can happen, I tried to check the code but it seems simple and already correct for me.
First of all C++ does not support variable length arrays and if an array is declared as having N elements then the valid range of indices is [0, N-1].
You could either dynamically allocate an array of the required size yourself or use standard container std::vector<int>.
Using std::vector<int> you could for example write
#include <iostream>
#include <vector>
int main()
{
unsigned int n = 0;
std::cout << "Enter number of elements: ";
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " elements: ";
for ( int &x : v ) std::cin >> x;
std::cout << "\nThe array is ";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
The program output might look like
Enter number of elements: 10
Enter 10 elements: 0 1 2 3 4 5 6 7 8 9
The array is 0 1 2 3 4 5 6 7 8 9
The first thing you have to look after is that dasblinkenlight has already mentioned in his answer, variable-length arrays are a language extension.
Then you should think that arrays are zero index based. What does this means? Let's consider an array of size 4 that is denoted as arr. Then it's elements can be accessed as arr[0], arr[1], arr[2], and arr[3]. So what happens when you run your first loop?
for(int i = 1; i<= N; i++) {
cin >> arr[i];
}
You set the a value for arr[1], arr[2] to arr[N]. But the arr[N] points to a place in memory that is not associated with the array, since the array's size is N and all arrays are zero based. The last element of the array lives in here arr[n-1].
Unfortunately in C++ there isn't any check for the length of an array and you are allowed to do things like this. For instance, if you had tried this in C# or in Java then you would have got an Index Out Of Range Exception.
If you change your code to the following, then you will get the expected output:
for(int i = 0; i<N; i++) {
cin >> arr[i];
}
for(int i = 0; i<N; i++) {
cout << arr[i] << endl;
}
Your code is not valid C++, because variable-length arrays are a language extension.
With that part out of our way, consider what happens in your first loop's last step: you are accessing an element past the end of the array, which is undefined behavior.
Your second loop is correct, though, so all you need to do is correcting the header of the first loop to match the header of the second loop.
An array of N elements has indexes from 0 to N-1 (so: N-1 - 0 + 1 = N elements, some maths.)
So fix this: for(int i = 1; i<= N; i++) with this : for(int i = 1; i< N; i++)

why I cannot cout my declared array character?

char ph[6]={'a','b','c','d','e','f'};
that is my code and this is how I summon them
for(int i=1;i>=3;i++)
{
cout<<ph[i]<<" ";
}
but it turn out blank
Your loop is never going to run.
for(int i=1;i>=3;i++)
Means start at 1 and while we are greater then 3 continue the loop. Since we are never greater than 3 the loop ends.
If you want to print the first 3 elements of the array, then you would use:
for(int i = 0; i < 3; i++)
cout<<ph[i]<<" ";

error in two-dimensional array code

I wrote a multiplication table like this:
#include <iostream>
#include <conio.h>
using namespace std;
int main(){
int table[9][9], i, j;
for (i = 0; i < 10; ++i){
for (j = 0; j < 10; ++j)
{
table[i][j] = (i + 1) * (j + 1);
cout << table[i][j] << "\t";
}
cout << endl;
}
_getch();
return 0;
}
And when I run it it gives me the right answer but when I press a key it throws this error:
run time check faliure #2-stack around the variable table was corrupted
But it doesn't throw that error when I change the code to this:
......
int main(){
**int table[10][10]**, i, j;
for (i = 0; i < 10; ++i){
......
If they both give the same answer then what's the difference??
You are overflowing your arrays, The max index in bounds is 8 (since the indices are zero based and you defined 9 cells as your dimensions size so 8 will be the last cell in each dimension) and your for loop can reach till 9 (including 9) which will cause an overflow.
The snippet int table[9] declares an array of size 9, that means valid indices are actually 0-8. But your loop iterates from 0 to 9. This causes a write into an invalid memory region (which doesn't belong to your array), therefore corrupting your stack.
Now you actually have a two dimensional array, but the problem remains the same.
You're going outside the array in your for loops. They should be:
for (i = 0; i < 9; ++i){
for (j = 0; j < 9; ++j)
The array indexes run from 0 to 8, but you were going up to 9 because your conditions were i < 10 and j < 10.
Arrays in C/C++ start with 0 index.
When you declare table[9][9] you reserve memory for 9x9 array with indexes 0..8, 0..8
but in for loop your upper index is 9 - it is out of array range
I guess you should declare table like you pointed:
int table[10][10];
You are accessing out of array's range element.
Your array is a 9x9 table but you are trying to access 10x10 table.
So either use i<9 and j<9 in your both loops or increase your array size to table[10][10].
Hope this might help.
Rule of thumb: in for loops, N in (i = 0; i < N; i++) clause should (almost always) be equal to the corresponding array's length. When you see either i <= N or i < N + 1, it's (most often) a sign of the dreaded off-by-one bug.