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?
Related
I have a return value from a library which is a void pointer. I know that it points to a short int; I try to obtain the int value in the following way (replacing the function call with a simple assignment to a void *):
short n = 1;
void* s = &n;
int k = *(int*)s;
I try to cast a void pointer that points to an address in which there is a short and I try to cast the pointer to point to an int and when I do so the output becomes a rubbish value. While I understand why it's behaving like that I don't know if there's a solution to this.
If the problem you are dealing with truly deals with short and int, you can simply avoid the pointer and use:
short n = 1;
int k = n;
If the object types you are dealing with are different, then the solution will depend on what those types are.
Update, in response to OP's comment
In a comment, you said,
I have a function that returns a void pointer and I would need to cast the value accordingly.
If you know that the function returns a void* that truly points to a short object, then, your best bet is:
void* ptr = function_returning_ptr();
short* sptr = reinterpret_cast<short*>(ptr);
int k = *sptr;
The last line work since *sptr evaluates to a short and the conversion of a short to an int is a valid operation. On the other hand,
int k = *(int*)sptr;
does not work since conversion of short* to an int* is not a valid operation.
Your code is subject to undefined behavior, as it violates the so-called strict aliasing rules. Without going into too much detail and simplifying a bit, the rule states that you can not access an object of type X though a pointer to type Z unless types X and Z are related. There is a special exception for char pointer, but it doesn't apply here.
In your example, short and int are not related types, and as such, accessing one through pointer to another is not allowed.
The size of a short is only 16 bits the size of a int is 32 bits ( in most cases not always) this means that you are tricking the computer into thinking that your pointer to a short is actually pointing to an integer. This causes it to read more memory that it should and is reading garbage memory. If you cast s to a pointer to a short then deference it it will work.
short n = 1;
void* s = &n;
int k = *(short*)s;
Assuming you have 2 byte shorts and 4 byte ints, There's 3 problems with casting pointers in your method.
First off, the 4 byte int will necessarily pick up some garbage memory when using the short's pointer. If you're lucky the 2 bytes after short n will be 0.
Second, the 4 byte int may not be properly aligned. Basically, the memory address of a 4 byte int has to be a multiple of 4, or else you risk bus errors. Your 2 byte short is not guaranteed to be properly aligned.
Finally, you have a big-endian/little-endian dependency. You can't turn a big-endian short into a little-endian int by just tacking on some 0's at the end.
In the very fortunate circumstance that the bytes following the short are 0, AND the short is integer aligned, AND the system uses little-endian representation, then such a cast will probably work. It would be terrible, but it would (probably) work.
The proper solution is to use the original type and let the compiler cast. Instead of int k = *(int*)s;, you need to use int k = *(short *)s;
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).
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.
I'm trying to store a couple of ints in memory using void* & then retrieve them but it keeps throwing "pointer of type ‘void *’ used in arithmetic" warning.
void *a = new char[4];
memset(a, 0 , 4);
unsigned short d = 7;
memcpy(a, (void *)&d, 2);
d=8;
memcpy(a+2, (void *)&d, 2); //pointer of type ‘void *’ used in arithmetic
/*Retrieving*/
unsigned int *data = new unsigned int();
memcpy(data, a, 2);
cout << (unsigned int)(*data);
memcpy(data, a+2, 2); //pointer of type ‘void *’ used in arithmetic
cout << (unsigned int)(*data);
The results are as per expectation but I fear that these warnings might turn into errors on some compiler. Is there another way to do this that I'm not aware of?
I know this is perhaps a bad practice in normal scenario but the problem statement requires that unsigned integers be stored and sent in 2 byte packets. Please correct me if I'm wrong but as per my understanding, using a char* instead of a void* would have taken up 3 bytes for 3-digit numbers.
a+2, with a being a pointer, means that the pointer is increased to allow space for two items of the pointer type. V.g., if a was int32 *, a + 2 would mean "a position plus 8 bytes".
Since void * has no type, it can only try to guess what do you mean by a + 2, since it does not know the size of the type being referred.
The problem is that the compiler doesn't know what to do with
a+2
This instruction means "Move pointer 'a' forward by 2 * (sizeof-what-is-pointed-to-by-'a')".
If a is void *, the compiler doesn't know the size of the target object (there isn't one!), so it gives an error.
You need to do:
memcpy(data, ((char *)a)+2, 2);
This way, the compiler knows how to add 2 - it knows the sizeof(char).
Please correct me if I'm wrong but as per my understanding, using a char* instead of a void* would have taken up 3 bytes for 3-digit numbers.
Yes, you are wrong, that would be the case if you were transmitting the numbers as chars. 'char*' is just a convenient way of referring to 8-bit values - and since you are receiving pairs of bytes, you could treat the destination memory are char's to do simple math. But it is fairly common for people to use 'char' arrays for network data streams.
I prefer to use something like BYTE or uint8_t to indicate clearly 'I'm working with bytes' as opposed to char or other values.
void* is a pointer to an unknown, more importantly, 0 sized type (void). Because the size is zero, offset math is going to result in zeros, so the compiler tells you it's invalid.
It is possible that your solution could be as simple as to receive the bytes from the network into a byte-based array. An int is 32 bits, 4 bytes. They're not "char" values, but quads of a 4-byte integer.
#include <cstdint>
uint8_t buffer[4];
Once you know you've filled the buffer, you can simply say
uint32_t integer = *(static_cast<uint32*>(buffer));
Whether this is correct will depend on whether the bytes are in network or host order. I'm guessing you'll probably need:
uint32_t integer = ntohl(*(static_cast<uint32*>(buffer)));
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.