Reputation: 67
I'm a programming and c++ novice. I'd appreciate some help with this.
the following program (in c++) doesn't encounter any problem either in compilation or run-time:
int main()
{
int b = 5;
int*a = &b;
*(a+5) = 6;
return 0;
}
But according to everything I learned it shouldn't work, because a is a pointer to a single variable. What am I missing here?
Upvotes: 3
Views: 159
Reputation: 19864
Just adding to the existing answers.
The access
*(a+5) = a[5]
So this is the location not allocated by you.
In the case of array say
int a[6];
You have a valid access from a[0]
to a[5]
where a[5]
is the last element of the array and any further access like a[6]
will lead to undefined behavior as that location is not allocated by you.
Similarly you just have a integer allocated like
int b=5;
int *a = &b;
a is a pointer pointing to &b
i.e address of b.
So the valid access for this is just a[0]
which is the only location allocated by you on the stack.
Any other access like a[1] a[2]...
and so on will lead to undefined behavior.
The access turns out to be VALID if you have something like
int b[6];
int *a = b;
Now a[5]
will give the value of the last element of the array b
Upvotes: 0
Reputation: 19445
The program do have an undefined behaviour:
int main()
{
//This cause the loading of the "main" function to allocate memory for variable b
//It could be in a memory page that was already allocated to the program
//or in a new allocated page.
int b = 5;
//Here a just getting the address of variable b.
int*a = &b;
//This is the undefined behavior and can end up in two cases:
// 1. If (a+5) value is in a memory space that is allocated to the application.
// Then no runtime error will happen, and the value will be writing there.
// probably dirting some other value, and can cause an undefined behavior later
// in the application execution.
// 2. If (a+5) value is in a memory space that wasn't allocated to the application.
// the application will crash
*(a+5) = 6;
return 0;
}
Now, since a page size is probably 4096 and b is somewhere within a page, *b+5 is in most cases still be in the same page. If you want to challenge it more change it from 5 to 5000 or higher and the chance for crashes will increase.
Upvotes: 1
Reputation: 31435
Your program should indeed not encounter any problem at compile time. It is all valid code with regards to compilation.
However it will encounter undefined behaviour at runtime as a+5
is not a valid address.
If you want to know why it should compile, you can write code like this:
int func( int * buf, size_t size )
{
for( size_t i = 0; i < size; ++i )
{
*(buf + size) = static_cast<int>(i); // or (int)i in C
}
}
int main()
{
int buf[ 6 ];
func( buf, 6 );
}
In your code a
is a pointer to memory. a + 5
means an address 5 "ints" on from where a
points. As a
was pointed at a single integer b
, there are no guarantees about such an address. Interestingly enough, it is well defined to refer to a+1
even though it points to a place in memory that you should not read from or write to. But the pointer itself has some guarantees, i.e. it will be greater than a
and if you subtract 1 from it you will get back to a
and if you do a ptrdiff between it and a
you will get 1. But that is just a special property of "one past the end" which allows programmers to specify memory ranges.
Upvotes: 6
Reputation: 12658
Yes it shouldn't work when you access memory space which is not in your process region, but perhaps no one has owned that particular region ((a + 5)
) which didn't cause run time illegal memory access or it can. Hence its a UB.
Upvotes: 0