0

When I want to change last element of array,I always use [-1] for last element.

#include <iostream>
using namespace std;
int main(){
    int arr[10]{};
    arr[0]=10;
    arr[-1]=100;
    cout<<arr[-1]<<endl;
    return 0;
}

Then my teacher say:"C++ doesn't support that kind of behavior with arrays.I should use arr[9] for last elemant and "arr[-1]=100" will actually store 1000 in the area one element before where the array begins. this can cause crash since that value is outside the bounds of the array." Can someone explain why?

Note:I am python programer.When I use -1 in list.I don't have problem in python. Does C++ have different condition ?

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
Tolga
  • 45
  • 1
  • 6
  • For any array or pointer `a` and index `i`, the expression `a[i]` is exactly equal to `*(a + i)`. Now think where `a - 1` would point. And if you don't understand pointers and pointer arithmetic, then please [get a couple of good C++ books to read](https://stackoverflow.com/a/388282/440558). – Some programmer dude Sep 17 '19 at 13:00
  • Arrays in C++ are indexed with an unsigned integer type, C++ just doesn't magically convert your -1 to the last element like python does. You can use Iterators like [std::begin()](https://en.cppreference.com/w/cpp/iterator/begin) and [std::end()](https://en.cppreference.com/w/cpp/iterator/end) though. – nada Sep 17 '19 at 14:13
  • When you're writing C++, please just try to ignore everything you know about programming from Python. – nada Sep 17 '19 at 14:17

2 Answers2

6

Your teacher is right. Accessing the array with arr[-1] is undefined behavior which is not healthy for your code, bad bad. C style arrays in C++ do not have the -1 feature as Python does.

For C style arrays you indeed have to do arr[9] for the last element. However for C++ style arrays (std::array) you can use size() - 1 or rbegin() or back().

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
  • @Quentin True, or the old `sizeof` trick. I kind of left that out to encourage OP to use `std::array` instead, don't ruin my speech you leek chewing exceptional person! – Hatted Rooster Sep 17 '19 at 14:23
  • 1
    I mean, that syntax *should* be abhorrent to whoever comes across my comment, but I get that it isn't obvious when compared to more... eclectic things I've had to write in the past. – Quentin Sep 17 '19 at 14:25
1

A C-style array (f.ex. int arr[10]) is just a handle to a reserved piece of memory, and indexing it is the same as taking the address of it and adding the index. That is:

arr[5] is the same as *(arr + 5) which is the same as "take the address of arr + (5 * sizeof(int) ). Then dereference the result and return whatever it points to". From this you should be able to see that your teacher is correct: arr[-1] will give you a couple of bytes of memory just before your array and then interpret that as an int.

And that is it! There are no boundary checks and you can't really add them either since the array does not even know how big it is (so, no .length() property either).

There is a good reason why one of the most common recommendations on this board to new C++ programmers is: Leave C-style arrays alone and use std::vector (or std::array) instead. std::vector is, as far as I know, the closest thing in C++ to the list you are used to in Python (though not the same, f.ex. vector also does not implement the -1 = last element trick).

Frodyne
  • 3,547
  • 6
  • 16
  • 1
    "*A C-style array [...] is just a pointer to a reserved piece of memory*" - this is incorrect. Arrays are not pointers. They decay to them. – Fureeish Sep 17 '19 at 14:07
  • @Fureeish I don't want to go into too many technical details with this answer, do you think my edit here is better? – Frodyne Sep 17 '19 at 14:19