Person1
Person1

Reputation: 67

Pointer behaves strangely

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

Answers (4)

Gopi
Gopi

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

Roee Gavirel
Roee Gavirel

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

CashCow
CashCow

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

Sunil Bojanapally
Sunil Bojanapally

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

Related Questions