Why does C++ multiply this value by 4? [closed] - c++

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.

Related

C++ adding 4 bytes to pointer address

I have a question about pointers, and memory addresses:
Supposing I have the following code:
int * array = (int *) malloc(sizeof(int) * 4);
Now in array im storing a memory address, I know that c++ takes already care when adding +1 to this pointer it will add 4 bytes, but what If I want to add manually 4 bytes?
array + 0x004
If im correct this will lead to add 4*4 (16) bytes, but my Idea is to add manually those 4 bytes.
Why? Just playing around, i've tried this and I got a totally different result from what I expected, then i've researched and i've seen that c++ takes already care when you add +1 to a pointer (it sums 4 bytes in this case).
Any idea?
For a pointer p to a type T with value v, the expression p+n will (on most systems anyway) result in a pointer to the address v+n*sizeof(T). To get a fixed-byte offset to the pointer, you can first cast it to a character pointer, like this:
reinterpret_cast<T*>(reinterpret_cast<char*>(p) + n)
In c++, sizeof(char) is defined to be equal to 1.
Do note that accessing improperly aligned values can have large performance penalties.
Another thing to note is that, in general, casting pointers to different types is not allowed (called the strict aliasing rule), but an exception is explicitly made for casting any pointer type to char* and back.
The trick is convert the type of array into any pointer-type with a size of 1 Byte, or store the pointer value in an integer.
#include <stdint.h>
int* increment_1(int* ptr) {
//C-Style
return (int*)(((char*)ptr) + 4);
}
int* increment_2(int* ptr) {
//C++-Style
char* result = reinterpret_cast<char*>(ptr);
result += 4;
return reinterpret_cast<int*>(result);
}
int* increment_3(int* ptr) {
//Store in integer
intptr_t result = reinterpret_cast<intptr_t>(ptr);
result += 4;
return reinterpret_cast<int*>(result);
}
Consider that if you add an arbitrary number of bytes to an address of an object of type T, it no longer makes sense to use a pointer of type T, since there might not be an object of type T at the incremented memory address.
If you want to access a particular byte of an object, you can do so using a pointer to a char, unsigned char or std::byte. Such objects are the size of a byte, so incrementing behaves just as you would like. Furthermore, while rules of C++ disallow accessing objects using incompatible pointers, these three types are excempt of that rule and are allowed to access objects of any type.
So, given
int * array = ....
You can access the byte at index 4 like this:
auto ptr = reinterpret_cast<unsigned char*>(array);
auto byte_at_index_4 = ptr + 4;
array + 0x004
If im correct this will lead to add 4*4 (16) bytes
Assuming sizeof(int) happens to be 4, then yes. But size of int is not guaranteed to be 4.

C++ pointer arithmetic logic [duplicate]

This question already has answers here:
Pointer Arithmetic In C
(2 answers)
Closed 8 years ago.
A project I did last year involved pointer arithmetic. When I did that, I was able to treat pointers like memory addresses and add or subtract from them as I wanted. For example, if int* p == array[0], then you'd know that p + sizeof(int) would find array[1]. That doesn't seem to be the case anymore, as I have a relatively well-known interview question in front of me in which I have to debug the following code:
void
ReverseTheArray( const short *pArrayStart, int nArrayByteLength )
{
short const *pArrayEnd = (pArrayStart + nArrayByteLength);
while(pArrayStart != pArrayEnd)
{
short tmp = *pArrayStart;
*pArrayStart = *pArrayEnd;
*pArrayEnd = tmp;
pArrayStart++;
pArrayEnd--;
}
}
Note the last two lines - I would have bet that these were wrong because simply adding 1 to the pointer wouldn't work, you would need to add sizeof(short). But from testing the code it would seem I'm wrong - "pArrayStart++" adds sizeof(short) to the pointer, not 1.
When did this change? Can anyone give me some insight into what I'm wrong about so that I can not look stupid if I'm asked about this?
Edit: Okay - seems like it's always been that way. My bad.
The type of pointer is merely for this purpose. "Pointer to int" means adding one would skip 4 bytes (if int is 4 bytes on that machine.
Update: (Of course, in addition to explaining what type of data it is pointing to).

What is the memory address of this pointer? [closed]

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

Difference of two addresses in C [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Pointer Arithmetic
The given code
int arr[12];
int * cur = arr;
cur++;
cout<<"cur-arr = "<<cur-arr<<endl;
Outputs 1, but I expected sizeof(int). Can someone please explain the nature of this behavior?
It's a defined behavior of C pointer arithmetic. It uses the size of pointed type as a unit. If you change subtraction in the last line to
(char *)cur - (char *)arr
you get 4 in the output.
This is the number of elements (ints here) between arr and cur (which is arr+1 at the time of subtraction). Compiler takes note that cur is a pointer to an integer and arr is an integer array. To get total number of bytes, try this:
(cur - arr) * sizeof(arr[0]);
cur is a pointer to int, initialized to some value (arr - the semantics of array-to-pointer conversion are irrelevant here), incremented (cur++) and compared to its old value. Unsurprisingly, it grew by one through the increment operation.
Pointer arithmetic with a given type works just like regular arithmetic. While the pointer is advanced by sizeof(int) bytes in this example, the difference between pointers is also calculated in units of sizeof(int), so you see plain simple arithmetics.
Addition and substraction for pointers works in accordance to the pointer type.

Pointer Question [closed]

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
Can you please explain to me what is happening here?
char data[128]; // Create char array of size 128.
long * ptr; // Create a pointer.
ptr = (long *) data; // ??
Mainly, what does the (long *) mean?
Does it mean that the data is of type char, and I am casting the reference to data as a reference to a long?
Thank you.
The (long*) expression is a C style cast. It treates the memory pointed to by data and treats it as a pointer to data of type long
It is a "C-style" cast; in your case, it translates into a "reinterpret cast". Read it as "take a pointer to a char type, and treat it as if it pointed to long". The preferred way to write it is reinterpret_cast<long>(ptr). Note that valid indexes are from 0 to 128 * sizeof(char) / sizeof(long) - 1, which may differ between platforms.
It is casting the data pointer as a pointer to a long.
The line:
char data[128];
will allocate 128 bytes of memory and treat that data as characters. The code:
long * ptr;
ptr = (long *) data;
allocates a pointer to a long, and sets that pointer to point at the memory allocated by char data[128];.
You can reference this memory by data[x] to get the xth character starting at the beginning of this memory block. Or you can reference this memory by ptr[x] to get the xth long starting at the beginning of this memory block. Just note that each long takes up more storage than each character. It is probably 8 bytes - so you can go up to data[127] or ptr[15].
(long *) is a typecast. Since data is an array of char, this typecast is needed to make the assignment to ptr, which is a long * pointer. Your "does it mean" sentence is correct.
This statement means, take data (which is the memory address of the start of 128 chars), and treat that memory address instead as the start of a long number.
This seems very risky and foolish.
Is there any particular reason this is being done?
(long *) is a cast. It tells the compiler "this here char[128] you've got? Treat it as a long *." But then you assign that to a char * pointer, which a) is an invalid assignment without a cast from long * to char *, and b) won't preserve the... longitude... of the variable.
Basically, it's pointless in this particular example. I suspect it's because you've modified the original code for display here--can you show us what it actually looks like?