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
Related
Value of a pointer is address of a variable. Why value of an int pointer increased by 4-bytes after the int pointer increased by 1.
In my opinion, I think value of pointer(address of variable) only increase by 1-byte after pointer increment.
Test code:
int a = 1, *ptr;
ptr = &a;
printf("%p\n", ptr);
ptr++;
printf("%p\n", ptr);
Expected output:
0xBF8D63B8
0xBF8D63B9
Actually output:
0xBF8D63B8
0xBF8D63BC
EDIT:
Another question - How to visit the 4 bytes an int occupies one by one?
When you increment a T*, it moves sizeof(T) bytes.† This is because it doesn't make sense to move any other value: if I'm pointing at an int that's 4 bytes in size, for example, what would incrementing less than 4 leave me with? A partial int mixed with some other data: nonsensical.
Consider this in memory:
[↓ ]
[...|0 1 2 3|0 1 2 3|...]
[...|int |int |...]
Which makes more sense when I increment that pointer? This:
[↓ ]
[...|0 1 2 3|0 1 2 3|...]
[...|int |int |...]
Or this:
[↓ ]
[...|0 1 2 3|0 1 2 3|...]
[...|int |int |...]
The last doesn't actually point an any sort of int. (Technically, then, using that pointer is UB.)
If you really want to move one byte, increment a char*: the size of of char is always one:
int i = 0;
int* p = &i;
char* c = (char*)p;
char x = c[1]; // one byte into an int
†A corollary of this is that you cannot increment void*, because void is an incomplete type.
Pointers are increased by the size of the type they point to, if the pointer points to char, pointer++ will increment pointer by 1, if it points to a 1234 bytes struct, pointer++ will increment the pointer by 1234.
This may be confusing first time you meet it, but actually it make a lot of sense, this is not a special processor feature, but the compiler calculates it during compilation, so when you write pointer+1 the compiler compiles it as pointer + sizeof(*pointer)
As you said, an int pointer points to an int. An int usually takes up 4 bytes and therefore, when you increment the pointer, it points to the "next" int in the memory - i.e., increased by 4 bytes. It acts this way for any size of type. If you have a pointer to type A, then incrementing a A* it will increment by sizeof(A).
Think about it - if you only increment the pointer by 1 byte, than it will point to a middle of an int and I can't think of an opportunity where this is desired.
This behavior is very comfortable when iterating over an array, for example.
The idea is that after incrementing, the pointer points to the next int in memory. Since ints are 4 bytes wide, it is incremented by 4 bytes. In general, a pointer to type T will increment by sizeof(T)
A pointer points at the BEGINNING of something in memory. An INT occupies 4 bytes (32bit) and a DOUBLE occupies 8 bytes (64bit) in memory. So if you have a DOUBLE number stored, and you wish at a very low level pointing to the next available memory location, the pointer wooud be increased by 8 bytes. If for some reason you pointed at +4bytes from the start of a DOUBLE value, you would corrupt it's value. Memory is a very large flat field that has no conscience of itself, so it's up to the software to divides it properly and to "respect the borders" of items located in that field.
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.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
pDosHeader is loaded into ECX
pDosHeader->f_lfanew is loaded into EAX (the value, not the pointer)
pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew);
The above code ades ECX + EAX and gets me the desired result... but apparently it's bad habbit to cast pointers to DWORD's if I decide to compile something on x64
pNtHeaders = (PIMAGE_NT_HEADERS)( (PDWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew );
pNtHeaders = (PIMAGE_NT_HEADERS)( (PDWORD)pDosHeader + pDosHeader->e_lfanew );
The above code adds ECX + EAX * 4 and gets me a result that I do not desire. for both 1 and 2.
My question is why? Why does C++ compile my code like this? Why does it multiply e_lfanew by 4 when I cast the dos header into a pointer?
Does it assume that I want to make my pointer point to the next element x number of times? Therefore multiplying it by 4 so that I can get to the e_lfanew(th) element instead of adding e_lfanew? It probably does.
So what do I do? What is the correct way of casting this code the C++ way so it gets the desired result while not using bad habits?
I don't want the e_lfanewth element of pDosHeader. I just want it to add e_lfanew to pDosHeader.
Why does it multiply e_lfanew by 4 when I cast the dos header into a pointer?
Because this is how pointer arithmetic works in both C and C++. When you add an integer to a pointer, the pointer is adjusted by the given number of elements, not bytes. Since PDWORD points to DWORD and DWORD is four bytes wide, adding n to it adds 4 * n to the address.
To make it work the way you want, change the pointer to PBYTE.
If you add a number to a pointer of type T, the pointer will increase by number*sizeof(T).
This should do what you want:
pNtHeaders = (PIMAGE_NT_HEADERS)( (char*)pDosHeader + pDosHeader->e_lfanew );
When you add an integer i to a pointer p as in p + i, this takes into account the size of the type of *p. For example, if p was a pointer to an int, and sizeof(int) was 4, then p+1 would be 4 bytes beyond p. (This is assuming that you are pointing to memory that you are allowed to point to, otherwise it is undefined.) Thus p[1] and *(p+1) are equivalent expressions.
To add an absolute number of bytes to a pointer, it must be a multiple of the size of the type being pointed to and you must convert it to a number of objects being pointed to. For example, for int *ip being incremented by a number of bytes int offset:
ip = ip + offset / sizeof(*ip);
This requires offset to be a multiple of sizeof(int).
This seems not the case in your problem though, if pDosHeader->e_lfanew is an arbitrary number of bytes. In this case use Master T's or NPE's solution, with a cast of the pointer to a char *. Normally casting between pointers to different types would be undefined behaviour, but there is an exception for char * under the aliasing rules, so that would work regardless of the type of pDosHeader.
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]
Value of a pointer is address of a variable. Why value of an int pointer increased by 4-bytes after the int pointer increased by 1.
In my opinion, I think value of pointer(address of variable) only increase by 1-byte after pointer increment.
Test code:
int a = 1, *ptr;
ptr = &a;
printf("%p\n", ptr);
ptr++;
printf("%p\n", ptr);
Expected output:
0xBF8D63B8
0xBF8D63B9
Actually output:
0xBF8D63B8
0xBF8D63BC
EDIT:
Another question - How to visit the 4 bytes an int occupies one by one?
When you increment a T*, it moves sizeof(T) bytes.† This is because it doesn't make sense to move any other value: if I'm pointing at an int that's 4 bytes in size, for example, what would incrementing less than 4 leave me with? A partial int mixed with some other data: nonsensical.
Consider this in memory:
[↓ ]
[...|0 1 2 3|0 1 2 3|...]
[...|int |int |...]
Which makes more sense when I increment that pointer? This:
[↓ ]
[...|0 1 2 3|0 1 2 3|...]
[...|int |int |...]
Or this:
[↓ ]
[...|0 1 2 3|0 1 2 3|...]
[...|int |int |...]
The last doesn't actually point an any sort of int. (Technically, then, using that pointer is UB.)
If you really want to move one byte, increment a char*: the size of of char is always one:
int i = 0;
int* p = &i;
char* c = (char*)p;
char x = c[1]; // one byte into an int
†A corollary of this is that you cannot increment void*, because void is an incomplete type.
Pointers are increased by the size of the type they point to, if the pointer points to char, pointer++ will increment pointer by 1, if it points to a 1234 bytes struct, pointer++ will increment the pointer by 1234.
This may be confusing first time you meet it, but actually it make a lot of sense, this is not a special processor feature, but the compiler calculates it during compilation, so when you write pointer+1 the compiler compiles it as pointer + sizeof(*pointer)
As you said, an int pointer points to an int. An int usually takes up 4 bytes and therefore, when you increment the pointer, it points to the "next" int in the memory - i.e., increased by 4 bytes. It acts this way for any size of type. If you have a pointer to type A, then incrementing a A* it will increment by sizeof(A).
Think about it - if you only increment the pointer by 1 byte, than it will point to a middle of an int and I can't think of an opportunity where this is desired.
This behavior is very comfortable when iterating over an array, for example.
The idea is that after incrementing, the pointer points to the next int in memory. Since ints are 4 bytes wide, it is incremented by 4 bytes. In general, a pointer to type T will increment by sizeof(T)
A pointer points at the BEGINNING of something in memory. An INT occupies 4 bytes (32bit) and a DOUBLE occupies 8 bytes (64bit) in memory. So if you have a DOUBLE number stored, and you wish at a very low level pointing to the next available memory location, the pointer wooud be increased by 8 bytes. If for some reason you pointed at +4bytes from the start of a DOUBLE value, you would corrupt it's value. Memory is a very large flat field that has no conscience of itself, so it's up to the software to divides it properly and to "respect the borders" of items located in that field.