I am studying for a midterm and one of the questions is Which of the following statements will increment a value in the array, and leave the pointer address unchanged? Circle 0 or more.
int array[10];
int * ptr = array;
1) *ptr++;
2)(*ptr)++;
3)*++ptr;
4)++*ptr;
I have seen 1 and 2 used before and I believe it's just getting the de-referenced values without changing the pointer. But I was surprised to find 3 and 4 is actually valid and I am confused as to how to understand or even read it? Is it the same thing? I believe the answer is that all 4 of them are valid.
http://en.cppreference.com/w/cpp/language/operator_precedence will be helpful to you. Read through it and put the parenthesis in to the examples based on the precedence of the operators and everything will hopefully make some sense.
The first would become *(ptr++) for instance.
Every C++ expression yields a value (main effect). There can also be side effects (as in the examples above) which occur before (e.g. pre-increment in
examples 3 and 4) or after (e.g. post-increment in examples 1 and 2) the main effect. So in your examples:
1) side effect occurs last:
main effect: dereference ptr to get array[0]
side effect: post increment ptr by 4 bytes (on a 32 bit machine)
2) side effect occurs last:
main effect: dereference ptr to get array[0]
side effect: post increment *ptr (=array[0]) by 1
3) side effect occurs first:
side effect: pre increment ptr by 4 bytes (on a 32 bit machine)
main effect: dereference *ptr to get array[0]
4) side effect occurs first:
side effect: pre increment *ptr (= array[0]) by 1
main effect: dereference *ptr to get array[0]
Notice the main effect is obtained by ignoring the side effect operator (++) and is therefore the same in all cases. The main effect is often combined with assignment as in:
int y = *++ptr; // ptr is incrented to point at array[1] and then y becomes equal to *ptr (= array[1])
Related
I am new to C++. I am learning some basics.
I tried the below program and got a run time error Stack around the variable x was corrupted.
int x = 56;
int *ptr = &x;
ptr[1]=8;
cout << *ptr << endl;
But if i update the index in line 3 to 0, say ptr[0] = 8, I am not getting any run time error and the console shows 8 as the output.
I assume 2 digits in the integer variable x and thought pointer index will have 0 and 1 as valid values. Why ptr[1] is causing run tume error where as ptr[2], ptr[3] does not cause any run times error and simply shows 56 as o/p.
Can any one help me to understand what is really going on here. May be a better tutorial site as an add on would help me to understand more on this subject.
ptr[1] is actually the integer next to the variable pointed to by ptr. Writing to such memory means overwriting about anything. You may overwrite other variables. Or return addresses. Or stack frames. Or about anything else. Heck, you may overwrite ptr itself, depending on how variables on the stack are arranged.
Undefined behavior. Compilers are allowed to assume it doesn't happen.
Let see what you are doing here (Lets assume int is 4 bytes):
int x = 56;
int *ptr = &x;
ptr[1]=8;
cout << *ptr << endl;
<- 4 bytes->......(rest of the stack)
----------------
| x | |
----------------
^ ^
ptr[0] ptr[1]
So, pre[1] is writing to a memory location which does not yet exist. So, you are writing data out-of-bound.
Presumably you were expecting ptr[1] to mean the second byte in x. But that's not how pointer arithmetic works. The pointer is an int*, so arithmetic is performed in "chunks" of int-sizes. Therefore, ptr[1] is the non-existent integer "next to" x.
You could probably see this working by making ptr a char* instead, but be careful because this is real hackery and probably not a good idea unless you really know what you're doing.
A further misconception is your indication that the number of decimal digits in the human-readable representation of x's value has anything to do with the number of bytes taking up by x in memory; it doesn't.
i have a question on pointer concept which i could not find a logical answer to
#include<conio.h>
#include<iostream.h>
void main()
{
int arr[10];
clrscr();
cout<<*arr+5 - *arr+3;
getch();
}
even if i assign arr[0]=10; (or any other value)
the compiler gives answer 8 but how . I can not see(understand) how operator precedence and associativity does solve it.
I will be grateful to you.
Because of *arr - *arr is 0 and 5 + 3 is 8.
The result you may be expecting is the result of:
cout<<(*arr+5) - (*arr+3);
The compiler gives answer 8 because that operation is simply equivalent to: (*arr - *arr) + 5 + 3 = 8. If you want to add the scalar to the pointer and then get the referenced value, you have to use parentheses *(arr+5).
If you look at the precedence table, for example here:
http://en.cppreference.com/w/cpp/language/operator_precedence
then you'll notice that the dereference operator (*) has higher priority than addition/subtraction (+/-) operators (they are in group no. 3 and 6 respectively). This is why the first operation that is performed is getting the value that the arr variable is pointing to, i.e. this part:
*arr
After this, the addition/subtraction is performed. The value that arr is pointing to doesn't matter since it gets reducted anyway.
This is how you should read this expression:
(*arr) + 5 - (*arr) + 3
and (*arr) - (*arr) is 0, no matter what value it points to.
EDIT: What I've written above is apparently true in your case and your compiler, but look at the #Konrad Rudolph comments to this answer.
And, if you are curious, how the compiler knows if, for example, the '*' should be treated as multiplication or dereference operator: it resolves this problem by looking at the number of arguments - if there's only one, than it's derefence, and if there are two, then it's multiplying.
I read that in function the local variables are put on stack as they are defined after the parameters has been put there first.
This is mentioned also here
5 .All function arguments are placed on the stack. 6.The instructions
inside of the function begin executing. 7.Local variables are pushed
onto the stack as they are defined.
So I excpect that if the C++ code is like this:
#include "stdafx.h"
#include <iostream>
int main()
{
int a = 555;
int b = 666;
int *p = &a;
std::cout << *(p+1);
return 0;
}
and if integer here has 4 bytes and we call the memory space on stack that contains first 8 bits of int 555 x, then 'moving' another 4 bytes to the top of the stack via *(p+1) we should be looking into memory at address x + 4.
However, the output of this is -858993460 - an that is always like that no matter what value int b has. Evidently its some standard value. Of course I am accessing a memory which I should not as for this is the variable b. It was just an experiment.
How come I neither get the expected value nor an illegal access error?
Where is my assumption wrong?
What could -858993460 represent?
What everyone else has said (i.e. "don't do that") is absolutely true. Don't do that. However, to actually answer your question, p+1 is most likely pointing at either a pointer to the caller's stack frame or the return address itself. The system-maintained stack pointer is decremented when you push something on it. This is implementation dependent, officially speaking, but every stack pointer I've ever seen (this is since the 16-bit era) has been like this. Thus, if as you say, local variables are pushed on the stack as they are initialized, &a should == &b + 1.
Perhaps an illustration is in order. Suppose I compile your code for 32 bit x86 with no optimizations, and the stack pointer esp is 20 (this is unlikely, for the record) before I call your function. This is what memory looks like right before the line where you invoke cout:
4: 12 (value of p)
8: 666 (value of b)
12: 555 (value of a)
16: -858993460 (return address)
p+1, since p is an int*, is 16. The memory at this location isn't read protected because it's needed to return to the calling function.
Note that this answer is academic; it's possible that the compiler's optimizations or differences between processors caused the unexpected result. However, I would not expect p+1 to == &b on any processor architecture with any calling convention I've ever seen because the stack usually grows downward.
Your assumptions are true in theory (From the CS point of view).
In practice there is no guarantee to do pointer arithmetic in that way expecting those results.
For example, your asumption "All function arguments are placed on the stack" is not true: The allocation of function argumments is implementation-defined (Depending on the architecture, it could use registers or the stack), and also the compiler is free to allocate local variables in registers if it feels necesary.
Also the asumption "int size is 4 bytes, so adding 4 to the pointer goes to b" is false. The compiler could have added padding between a and b to ensure memory aligment.
The conclusion here is: Don't use low-level tricks, they are implementation-defined. Even if you have to (Regardless of our advises) do it, you have to know how the compiler works and how it generates the code.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Ok, so on a test I had this question asked:
int* ptrA; // assigned memory address 100
int a = 1; // assigned memory address 600
ptrA = &a;
What is the memory address of ptrA + 2?
I thought it was 606 (int is 4 bytes + the address of a which is 600 + 2 = 606 but apparently the answer was 608, what am I missing to make this true?
It's undefined behavior, the expression PtrA + 2 is illegal. You can only do pointer arithmetic on pointers you own and can't add or substract to/from pointers outside the range of an array you own or one beyond the range.
We can still analyze this however (although useless, because of UB). You assume the address of a is 600 + 2, but it's not, since probably sizeof(int*) is also 4, so this becomes 600 + 4. So you get 600 + 4 + 4 = 608.
Actually Arithmetic operations on Pointers are different. They Increase depends on the size of data type so if one address is given say x and u have to ask for x+ 2.. (given x is a integer Pointer) then ..
x+ 2 means ---- x + (sizeof(int))*2
if x is given as char pointer then
x+2 means ---- x + (sizeof(char))*2
Thanks.
In C, x + y where x is a pointer is equivalent to &x[y]. Suppose that you had
int abc[3] = {1,2,3};
int* ptr = &abc[0];
&ptr[2] (ptr + 2) is the address of the 3, which is clearly 8 more than the address of the 1.
int* PtrA; // assigned memory address 100
int a = 1; // assigned memory address 600
What is the memory address of ptrA + 2?
The question is ambiguous.
If the question is "What is (the memory address of ptrA) + 2?", then you've said ptrA is at memory address 100 (ignoring PtrA != ptrA), and adding 2 to a pointer in C and C++ increments things in multiples of the pointed-to type's size, so if int is 32 bits then the final result is 100 + 2 * 4 = 108.
If the question is "What is the memory address of (ptrA + 2)?", meaning the result of adding the value in the ptrA variable and 2, then that is undefined as no initialisation of ptrA is shown and it's undefined behaviour to try to read from uninitialised memory.
Your expectations and the supposed answer suggest the intended code had...
ptrA = &a;
...sometime before the ptrA + 2 was to be evaluated. If that were true, then the answer would be 600 + 2 * sizeof(int), which is very likely to be 608.
In C/C++ the pointer arithmetic uses the size of the object that the pointer is pointing at. Ex:
int* PtrA = (int*)600;
The value of PtrA+2 will be 608 provided that the size of integer is 4.
Standard allows to do pointer arithmetic only inside arrays or "right after the array". This means that certain care should be taken.
I think, it is not true that address will always be more. It can be less as well. What is sure is that say ptr is pointer to base address of an array a of integers, then ptr+2 will point to 3rd element of the array. So if base address of array is 600, then address can be 600+2*(sizeofIint)) or it may be 600-2*sizeof(int); But in anycase, it will point to 3rd element of that array. So, I believe that even in cases of arrays, we should not rely on direct addresses. and should not make any assumptions about whether ptr+2 will point to 608 or something else.
Thanks & Regards,
Saurabh
In attempt to explain that arrays are just pointers (in C++) to our class, my professor showed us this:
array[5] // cout'ing this
*(array + 5) // would return the same value as this
I'm having a little trouble completely understanding it. Here's my thinking:
array is the address of the first location and so if we add 5 to that address, we move 5 addresses in memory. The pointer operator pulls the data from the memory location.
Is this the correct idea? The idea still feels foggy with me and just feel like I don't understand it completely. I think hearing someone else explain it might help me understand it more. Thanks in advance!
You've got the right idea.
Arrays implicitly cast to pointers. Interestingly, [] works on pointers, not arrays.
a[b] Subscript operator is defined as *(a + (b)). [] is used as syntactic sugar - it's much more pleasant to write array[5] instead of *(array + 5)
Pointer arithmetic with a pointer and an integer p + i increases the address at p by i * sizeof(*p) bytes.
char* p;
p + 5; // address increased by 5
int* p;
p + 5; // address increased by 20 as sizeof(*p) is 4
The * operator performs indirection. It will give you what the pointer is pointing to.
int x[2];
int* p = &x[0]; // could also be int* p = x;
*p = 5; // x[0] is now 5
*(p + 1) = 10; // x[1] is now 10
Your professor is correct that the two expressions will produce the same results. Your explanation of it leads me to believe you have a good grasp of the mechanics.
It is not quite correct to say an array is the same as a pointer. An array is very easily converted to a pointer, which leads to some confusion.
For example consider this code:
int array[5];
int * pointer = new int[5];
cout << sizeof(array); // outputs 5*sizeof(int), most probably 20
cout << sizeof(pointer); // outputs sizeof(int*), most probably 4 on a 32 bit OS
array[4] = 906;
pointer[4] = 906;
cout << *(array + 4) << *(pointer + 4); // outputs "906 906"
from memory arrays in c++ are sections of continuous memory the program. thats why you can go *(array + 5) as it is 5 from the front of the array.
Also keep in mind that arrays in C++ start # 0 so thus the 6th element in an array is array[5]
example
[0] [1] [2] [3] [4] [5] Array index
1 2 3 4 5 6 Item number
To access item 2 u would either
array[1]
*(array+1)
but please keep in mind array[index_number] is standard syntax for looking up an item in an array so make sure u use array[index_num] instead of *(array + index_num)
Yes, what your proffessor said is correct.
to explain it in detail
Consider your array,
int array[5]
here it takes 5 location in the memory say 0x00 0x04 0x08 0x0C and 0x10 0x14
Assuming integer takes 4 bytes, the locations are 4 bytes apart.
it this case 'array' represents the base address (pointer) to the array, that is 0x00. And the type of a would be int *. (since the type of the array elements is integer)
If you do array+1, it will be 0x04, since the increment of the pointer depends on the type of the pointer. If the pointer is integer, it will increment by 4 bytes. If the type of the integer is character, the pointer would increment by one bytes.
so if you do (array+5) it would point to the address 0x14 and
*(array+5)
returns the value of the location 0x14 which is the value at 5th location of array.
so in practical, array[5] is equal to *(array+5)
The compiler internally converts array[5] to *(array+5)
so even if we write 5[array], it will get converted it to *(5+array)
Though it seems strange, this is the reason why 5[array] works same as array[5]