Offset / Dereference question regarding arrays

Hello I have a brief question regarding arrays and the [] operator.
I understood that [] "Returns a reference to the element located n elements ahead of the element pointed by the iterator"

In my code, I first declared parray = array;
Then I ran a loop as it is and everything was fine, I get printout of 0, 1, 2, 3, 4.

Why does it still work even when I do (parray + 5)? From what I understand, if I do (parray + 5) and then try to do parray[something] in the loop, it will be accessing not the somethingth slot of the array but the (something + 5) slot. Yet, it still works and I have no array out of bounds or anything.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

int main (){
  int size;
  int *parray;
  
  cin >> size;
  
  int array[size];

  parray = array;
  (parray+5);
  
  for(int i = 0; i < size; i++){
    parray[i] = i;
    cout << parray[i] << endl;
  }
}


yakov@kulinich:~/Documents/examples$ ./example8
5
0
1
2
3
4


Here is the other version, with (parray + 5) removed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;

int main (){
  int size;
  int *parray;
  
  cin >> size;
  
  int array[size];

  parray = array;
    
  for(int i = 0; i < size; i++){
    parray[i] = i;
    cout << parray[i] << endl;
  }
}


yakov@kulinich:~/Documents/examples$ ./example8
5
0
1
2
3
4


Can you explain why the first version works? I would have guessed it would be trying to access the 5th, 6th, 7th, 8th 9th slot of an array that only has 0, 1, 2, 3, 4 slots...

Also, why does it compile and allow me to make the size of the array in runtime? I thought that was illegal???
Last edited on
Generally I'd do this so I wouldn't come across this problem:
1
2
3
4
5
int size;
int* parray;
cin >> size;

parray = new int[size];

Which is assigning a pointer to the newly created integer array object.

Not sure what "(parray+5)" would do.
Last edited on
You're probably using GNU, which permits creating an array like that. It's non-standard, so that is best avoided.

(parray+5); is a no-op. It adds 5 to a temporary copy of parray, which is then discarded. You'd have to use assignment (parray+=5;) to change parray.
Last edited on
Thanks for the reply. I agree that (parray+5) wont do anything. However, using the same logic, (and now another method), when I did (parray += 5), and ran the program, I got nothing. Shouldn't (parray+=5) increment the address that parray is pointing to by 5?

So, as a rule of thumb, even though GNU (yes I'm using it) allows creating an array like that, it is correct to use dynamic memory when the size of the array is not a constant during compilation?
You got nothing? Did you use 5 as an input? I assure you, parray += 5; will increase parray by 5 times the size of what it points to (5 * sizeof(int)). It may be hitting a null byte (possibly by random chance) and that terminates the cout.

Yes, you should use dynamic memory allocation when the size varies at runtime.
Yes, when i did parray += 5, then ran that loop, i still got 0, 1, 2, 3, 4

From what I think, since parray += 5 will increase it by (5 * sizeof(int)), when I run my loop and try to set parray[i], I should be getting an array out of bounds.


Out of bounds causes undefined behaviour
Undefined behaviour is undefined.
Topic archived. No new replies allowed.