Finding the value stored in an memory C/C++ - c++

Lets say i have an function which takes an integer value, Now, in the function i want to know the value which is stored in the memory location pointed by that integer value.
void function(int a)
{
//say, a=10 then I want to know the value stored in memory address 10
}

int is not a suitable type for passing pointers reliably on any system, without a risk of causing undefined behavior.
Starting with C99 / C++11 you can use uintptr_t type, which can be converted to and from a pointer:
// In C++ include <cstdint>
#include <stdint.h>
void function(uintptr_t a) {
uint8_t *ptr = (uint8_t*)a;
uint8_t val = *ptr;
}

In C++:
int function(int a)
{
return *reinterpret_cast<int*>(a);
}
Or in C (also works in C++):
int function(int a)
{
return *(int*)a;
}
Of course this will only work if the address actually fit into an int in the first place; on 64-bit systems where int is 32 bits wide, it doesn't really make sense. You could use uintptr_t as the argument type instead, as that is guaranteed to be wide enough to hold an address (i.e. a pointer).
And I chose to interpret the memory location as an int, but you need to use the appropriate return type (e.g. if the address is at the end of a page and you dereference a 4-byte int, your program may crash).

Related

Obtaining an int from a void pointer which points to a short

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;

cast to ‘uint32_t’ loses precision [duplicate]

I have a function with prototype void* myFcn(void* arg) which is used as the starting point for a pthread. I need to convert the argument to an int for later use:
int x = (int)arg;
The compiler (GCC version 4.2.4) returns the error:
file.cpp:233: error: cast from 'void*' to 'int' loses precision
What is the proper way to cast this?
You can cast it to an intptr_t type. It's an int type guaranteed to be big enough to contain a pointer. Use #include <cstdint> to define it.
Again, all of the answers above missed the point badly. The OP wanted to convert a pointer value to a int value, instead, most the answers, one way or the other, tried to wrongly convert the content of arg points to to a int value. And, most of these will not even work on gcc4.
The correct answer is, if one does not mind losing data precision,
int x = *((int*)(&arg));
This works on GCC4.
The best way is, if one can, do not do such casting, instead, if the same memory address has to be shared for pointer and int (e.g. for saving RAM), use union, and make sure, if the mem address is treated as an int only if you know it was last set as an int.
Instead of:
int x = (int)arg;
use:
int x = (long)arg;
On most platforms pointers and longs are the same size, but ints and pointers often are not the same size on 64bit platforms. If you convert (void*) to (long) no precision is lost, then by assigning the (long) to an (int), it properly truncates the number to fit.
There's no proper way to cast this to int in general case. C99 standard library provides intptr_t and uintptr_t typedefs, which are supposed to be used whenever the need to perform such a cast comes about. If your standard library (even if it is not C99) happens to provide these types - use them. If not, check the pointer size on your platform, define these typedefs accordingly yourself and use them.
Casting a pointer to void* and back is valid use of reinterpret_cast<>. So you could do this:
pthread_create(&thread, NULL, myFcn, new int(5)); // implicit cast to void* from int*
Then in myFcn:
void* myFcn(void* arg)
{
int* data = reinterpret_cast<int*>(arg);
int x = *data;
delete data;
Note: As sbi points out this would require a change on the OP call to create the thread.
What I am trying to emphasis that conversion from int to pointer and back again can be frough with problems as you move from platform to platform. BUT converting a pointer to void* and back again is well supported (everywhere).
Thus as a result it may be less error prone to generate a pointer dynamcially and use that.
Remembering to delete the pointer after use so that we don't leak.
Instead of using a long cast, you should cast to size_t.
int val= (int)((size_t)arg);
The proper way is to cast it to another pointer type. Converting a void* to an int is non-portable way that may work or may not! If you need to keep the returned address, just keep it as void*.
Safest way :
static_cast<int>(reinterpret_cast<long>(void * your_variable));
long guarantees a pointer size on Linux on any machine. Windows has 32 bit long only on 64 bit as well. Therefore, you need to change it to long long instead of long in windows for 64 bits.
So reinterpret_cast has casted it to long type and then static_cast safely casts long to int, if you are ready do truncte the data.
There is no "correct" way to store a 64-bit pointer in an 32-bit integer. The problem is not with casting, but with the target type loosing half of the pointer. The 32 remaining bits stored inside int are insufficient to reconstruct a pointer to the thread function. Most answers just try to extract 32 useless bits out of the argument.
As Ferruccio said, int must be replaced with intptr_t to make the program meaningful.
If you call your thread creation function like this
pthread_create(&thread, NULL, myFcn, reinterpret_cast<void*>(5));
then the void* arriving inside of myFcn has the value of the int you put into it. So you know you can cast it back like this
int myData = reinterpret_cast<int>(arg);
even though the compiler doesn't know you only ever pass myFcn to pthread_create in conjunction with an integer.
Edit:
As was pointed out by Martin, this presumes that sizeof(void*)>=sizeof(int). If your code has the chance to ever be ported to some platform where this doesn't hold, this won't work.
I would create a structure and pass that as void* to pthread_create
struct threadArg {
int intData;
long longData;
etc...
};
threadArg thrArg;
thrArg.intData = 4;
...
pthread_create(&thread, NULL, myFcn, (void*)(threadArg*)&thrArg);
void* myFcn(void* arg)
{
threadArg* pThrArg = (threadArg*)arg;
int computeSomething = pThrArg->intData;
...
}
Keep in mind that thrArg should exist till the myFcn() uses it.
What you may want is
int x = reinterpret_cast<int>(arg);
This allows you to reinterpret the void * as an int.
//new_fd is a int
pthread_create(&threads[threads_in_use] , NULL, accept_request, (void*)((long)new_fd));
//inside the method I then have
int client;
client = (long)new_fd;
Hope this helps
Don't pass your int as a void*, pass a int* to your int, so you can cast the void* to an int* and copy the dereferenced pointer to your int.
int x = *static_cast<int*>(arg);
In my case, I was using a 32-bit value that needed to be passed to an OpenGL function as a void * representing an offset into a buffer.
You cannot just cast the 32-bit variable to a pointer, because that pointer on a 64-bit machine is twice as long. Half your pointer will be garbage. You need to pass an actual pointer.
This will get you a pointer from a 32 bit offset:
int32 nOffset = 762; // random offset
char * pOffset = NULL; // pointer to hold offset
pOffset += nOffset; // this will now hold the value of 762 correctly
glVertexAttribPointer(binding, nStep, glType, glTrueFalse, VertSize(), pOffset);
A function pointer is incompatible to void* (and any other non function pointer)
Well it does this because you are converting a 64 bits pointer to an 32 bits integer so you loose information.
You can use a 64 bits integer instead howerver I usually use a function with the right prototype and I cast the function type :
eg.
void thread_func(int arg){
...
}
and I create the thread like this :
pthread_create(&tid, NULL, (void*(*)(void*))thread_func, (void*)arg);

Safely cast void* to int

If application is compiled to yield a x32 image then depending on architecture integer type may be 16 bits wide, 32s bit wide or anything more than 2 bytes. Size of void* will be 4 (on x32 always 4???). This would mean that passing int to void* is fine, but if it turns out that on a given architecture void* is wider than int (which is only guaranteed to be at least 2 bytes by the Standard) than in the face of
C Standard n1124 § 6.3.2.3 Pointers
5 An integer may be converted to any pointer type. Except as
previously specified, the result is implementation-defined, might not
be correctly aligned, might not point to an entity of the referenced
type, and might be a trap representation.56)
6 Any pointer type may be converted to an integer type. Except as
previously specified, the result is implementation-defined. If the
result cannot be represented in the integer type, the behavior is
undefined. The result need not be in the range of values of any
integer type.
casting void* to int may produce undefined behavior in the following snippet.
typedef enum tagENUM
{
WSO_1,
WSO_2,
//...
WSO_COUNT
} ENUM;
/* I cannot change handler signature because this is callback. I have to cast void*
* to ENUM however inside */
void handler( int i, int j, void *user_data)
{
ENUM mOperation;
mOperation = (ENUM)reinterpret_cast<int>(user_data);
}
// somewhere
handler( 1, 2, (void*)WSO_1); // UB? We can imagine that someone passes to handler
// (void*)WSO_131072 which don't fit into 16 bits
// So is there a place opened for UB?
If this is correct that possibility for nasal deamons is opened - how do I then write thiss cast safely? Can I use intptr_t to make sure the result will fit?
void handler( int i, int j, void *user_data)
{
ENUM mOperation;
uintptr_t p_mOperation = reinterpret_cast<uintptr_t>( user_data);
if ( p_mOperation > WSO_COUNT ) {
send_error(conn, 500, http_500_error, "Error: %s", strerror(ERRNO));
return;
}
mOperation = static_cast<ENUM_WS_OPERATION>( p_mOperation); // now safe?
Yes, it can cause undefined behaviour. If you use intptr_t instead then there is no undefined behaviour.
However, usually you can rewrite your code so that the pointer points to the intended integer, rather than being intended to be cast to it.
In your second example you have a mishmash. You want to use either use intptr_t, or void * that points to int. Not intptr_t * or uintptr_t *.
My preferred solution is that user_data always points to the data; and the type of the data being pointed to is determined by the handler being called or another parameter.
This bit:
mOperation = (ENUM)reinterpret_cast<int>(user_data);
suggests you've lost control of what you're doing already. You're doing a double cast which is always indicative of bad things going on (as if the reinterpret_cast wasn't already indicating that).
It's not clear from this what you're trying to do. Certainly (void*) is an inappropriate cast for passing values that aren't data. It's for passing pointers to arbitrary buffers of data where one hopes the thing at the other end can work out from the data what it needs to do with it.
So this:
handler( 1, 2, (void*)WSO_1);
is just plain wrong.
However, given that WSO_1 is in fact an enum, and I don't know of any platform where a void * is actually smaller than an enum, you should be OK to do
mOperation = reinterpret_cast<ENUM>(user_data);
The client has already gone into dubious areas when he's cast the enum into a void *, and that cast isn't going to make it any worse.

What does ampersand mean here?

The & below looks to be a new feature (c++ 11?) instead of just extracting the address of a variable, since put it (&) in different position makes the value t different. What does it mean?
// test_ampersand.cpp
int _tmain(int argc, _TCHAR* argv [])
{
int a[10] = { 2, };
int* p = a;
int t = (int) *((short *&) p);
// int t = (int) *((short *) &p);
return 0;
}
short *& is a reference to a pointer to short. This is plain C++. It's not really needed there anyway, because the result is never used as an lvalue - the pointer just gets dereferenced as an rvalue right away.
It's not a new feature, it's simply a reference - and it's casting p to a reference to short*. In other words, you're telling the compiler: "think the bytes comprising p are of type short*." (It also means you could assign to them like that, but that doesn't apply here).
The difference between a cast from int* to short* and one to short* & depends on the processor architecture. In case int* and short* have the same representation in memory, there is no difference. It will simply change what dereferencing the pointer gives you.
However, if you were on a (perhaps hypothetical) platform where a short is smaller than an int and at the same time an int is the smallest normally addressable unit, it would actually be quite different. The reason is that in such case, a short* would have to store an address (of an int) and also and offset of the short within that int. So it would be the case that sizeof(int*) < sizeof(short*). Note that there are actual architectures where sizeof(int*) < sizeof(char*) for precisely this reason, so it's not so far-fetched.
On such architecture, a cast int* -> short* would mean "compute a representation of short* such that it points to the same location as the original int*." A cast int* -> short*& would mean "interpret the representation of int* as a short*." That might even be invalid code, if sizeof(int*) < sizeof(short*) on such a platform.

error: cast from 'void*' to 'int' loses precision

I have a function with prototype void* myFcn(void* arg) which is used as the starting point for a pthread. I need to convert the argument to an int for later use:
int x = (int)arg;
The compiler (GCC version 4.2.4) returns the error:
file.cpp:233: error: cast from 'void*' to 'int' loses precision
What is the proper way to cast this?
You can cast it to an intptr_t type. It's an int type guaranteed to be big enough to contain a pointer. Use #include <cstdint> to define it.
Again, all of the answers above missed the point badly. The OP wanted to convert a pointer value to a int value, instead, most the answers, one way or the other, tried to wrongly convert the content of arg points to to a int value. And, most of these will not even work on gcc4.
The correct answer is, if one does not mind losing data precision,
int x = *((int*)(&arg));
This works on GCC4.
The best way is, if one can, do not do such casting, instead, if the same memory address has to be shared for pointer and int (e.g. for saving RAM), use union, and make sure, if the mem address is treated as an int only if you know it was last set as an int.
Instead of:
int x = (int)arg;
use:
int x = (long)arg;
On most platforms pointers and longs are the same size, but ints and pointers often are not the same size on 64bit platforms. If you convert (void*) to (long) no precision is lost, then by assigning the (long) to an (int), it properly truncates the number to fit.
There's no proper way to cast this to int in general case. C99 standard library provides intptr_t and uintptr_t typedefs, which are supposed to be used whenever the need to perform such a cast comes about. If your standard library (even if it is not C99) happens to provide these types - use them. If not, check the pointer size on your platform, define these typedefs accordingly yourself and use them.
Casting a pointer to void* and back is valid use of reinterpret_cast<>. So you could do this:
pthread_create(&thread, NULL, myFcn, new int(5)); // implicit cast to void* from int*
Then in myFcn:
void* myFcn(void* arg)
{
int* data = reinterpret_cast<int*>(arg);
int x = *data;
delete data;
Note: As sbi points out this would require a change on the OP call to create the thread.
What I am trying to emphasis that conversion from int to pointer and back again can be frough with problems as you move from platform to platform. BUT converting a pointer to void* and back again is well supported (everywhere).
Thus as a result it may be less error prone to generate a pointer dynamcially and use that.
Remembering to delete the pointer after use so that we don't leak.
Instead of using a long cast, you should cast to size_t.
int val= (int)((size_t)arg);
The proper way is to cast it to another pointer type. Converting a void* to an int is non-portable way that may work or may not! If you need to keep the returned address, just keep it as void*.
Safest way :
static_cast<int>(reinterpret_cast<long>(void * your_variable));
long guarantees a pointer size on Linux on any machine. Windows has 32 bit long only on 64 bit as well. Therefore, you need to change it to long long instead of long in windows for 64 bits.
So reinterpret_cast has casted it to long type and then static_cast safely casts long to int, if you are ready do truncte the data.
There is no "correct" way to store a 64-bit pointer in an 32-bit integer. The problem is not with casting, but with the target type loosing half of the pointer. The 32 remaining bits stored inside int are insufficient to reconstruct a pointer to the thread function. Most answers just try to extract 32 useless bits out of the argument.
As Ferruccio said, int must be replaced with intptr_t to make the program meaningful.
If you call your thread creation function like this
pthread_create(&thread, NULL, myFcn, reinterpret_cast<void*>(5));
then the void* arriving inside of myFcn has the value of the int you put into it. So you know you can cast it back like this
int myData = reinterpret_cast<int>(arg);
even though the compiler doesn't know you only ever pass myFcn to pthread_create in conjunction with an integer.
Edit:
As was pointed out by Martin, this presumes that sizeof(void*)>=sizeof(int). If your code has the chance to ever be ported to some platform where this doesn't hold, this won't work.
I would create a structure and pass that as void* to pthread_create
struct threadArg {
int intData;
long longData;
etc...
};
threadArg thrArg;
thrArg.intData = 4;
...
pthread_create(&thread, NULL, myFcn, (void*)(threadArg*)&thrArg);
void* myFcn(void* arg)
{
threadArg* pThrArg = (threadArg*)arg;
int computeSomething = pThrArg->intData;
...
}
Keep in mind that thrArg should exist till the myFcn() uses it.
What you may want is
int x = reinterpret_cast<int>(arg);
This allows you to reinterpret the void * as an int.
//new_fd is a int
pthread_create(&threads[threads_in_use] , NULL, accept_request, (void*)((long)new_fd));
//inside the method I then have
int client;
client = (long)new_fd;
Hope this helps
Don't pass your int as a void*, pass a int* to your int, so you can cast the void* to an int* and copy the dereferenced pointer to your int.
int x = *static_cast<int*>(arg);
In my case, I was using a 32-bit value that needed to be passed to an OpenGL function as a void * representing an offset into a buffer.
You cannot just cast the 32-bit variable to a pointer, because that pointer on a 64-bit machine is twice as long. Half your pointer will be garbage. You need to pass an actual pointer.
This will get you a pointer from a 32 bit offset:
int32 nOffset = 762; // random offset
char * pOffset = NULL; // pointer to hold offset
pOffset += nOffset; // this will now hold the value of 762 correctly
glVertexAttribPointer(binding, nStep, glType, glTrueFalse, VertSize(), pOffset);
A function pointer is incompatible to void* (and any other non function pointer)
Well it does this because you are converting a 64 bits pointer to an 32 bits integer so you loose information.
You can use a 64 bits integer instead howerver I usually use a function with the right prototype and I cast the function type :
eg.
void thread_func(int arg){
...
}
and I create the thread like this :
pthread_create(&tid, NULL, (void*(*)(void*))thread_func, (void*)arg);