Any ideas for this typecasting problem?
Here's what I am trying to do. This is not the actual code:
LinkedList* angles;
double dblangle;
dblangle = (some function for angle calculation returning double value);
(double*)LinkedListCurrent(angles) = &double;
I hope you get the idea. The last line is causing the problem. Initially angles is void* type so I have to first convert it to double*.
You use the unary * operator to dereference a pointer. Dereferencing a pointer means extracting the value pointed to, to get a value of the original type.
// Create a double value
double foo = 1.0;
// Create a pointer to that value
double *bar = &foo;
// Extract the value from that pointer
double baz = *bar;
edit 2: (deleted edit 1 as it was not relevant to your actual question, but was based on a miscommunication)
From your clarification, it looks like you are wondering how to set a value pointed to by a pointer that has been cast from a void * to a double *. In order to do this, we need to use the unary * on the left hand side of the assignment, in order to indicate that we want to write to the location pointed to by the pointer.
// Get a void * pointing to our double value.
void *vp = &foo;
// Now, set foo by manipulating vp. We need to cast it to a double *, and
// then dereference it using the * operator.
*(double *)vp = 2.0;
// And get the value. Again, we need to cast it, and dereference it.
printf("%F\n", *(double *)vp);
So, I'm assuming that your LinkedListCurrent is returning a void * pointing to some element in the linked list that you would like to update. In that case, you would need to do the following:
*(double*)LinkedListCurrent(angles) = dbangle;
This updated the value pointed to by the pointer returned from LinkedListCurrent to be equal to dbangle. I believe that is what you are trying to do.
If you are trying to update the pointer returned by LinkedListCurrent, you can't do that. The pointer has been copied into a temporary location for returning from the function. If you need to return a pointer that you can update, you would have to return a pointer to a pointer, and update the inner one.
My explanation above is based on what I believe you are trying to do, based on the example snippet you posted and some guesses I've made about the interface. If you want a better explanation, or if one of my assumptions was bad, you might want to try posting some actual code, any error messages you are getting, and a more detailed explanation of what you are trying to do. Showing the interface to the linked list data type would help to provide some context for what your question is about.
edit 3: As pointed out in the comments, you probably shouldn't be casting here anyhow; casts should be used as little as possible. You generally should use templated collection types, so your compiler can actually do typechecking for you. If you need to store heterogenous types in the same structure, they should generally share a superclass and have virtual methods to perform operations on them, and use dynamic_cast if you really need to cast a value to a particular type (as dynamic_cast can check at runtime that the type is correct).
why on earth would you want to use a memory address as a floating point number?
if you meant dereference:
double d = 1.0; // create a double variable with value 1.0
double *dp = &d; // store its address in a pointer
double e = *dp; // copy the value pointed at to another variable
Note this line:
(double*)LinkedListCurrent(angles) = &double;
where you've written &double, it i think should be &dbangle. To improve readability, I would write:
((double*)LinkedListCurrent(angles)) = &dbangle;
However, you should not do this type of conversion as others mentioned.
Use a union. If you want the store two variables in one memory location (but not at the same time), you don't have to pretend that one is the other.
union double_and_ptr {
double d;
double *p;
};
double_and_ptr x, y;
x.d = 0.1;
y.p = &x.d; // store a pointer in the same place as a double
y.d = x.d * 1.2; // store a double in the same place as a ptr
Use reinterpret_cast.
double foo = 3.0;
double* pfoo = &foo;
double bar = reinterpret_cast<double>(pfoo);
In answer to this:
I want to do the opposite of what you have done here. I want to copy the value from the pointer to the d floating point number. How can I do that?
You would do something like this:
// declare a pointer to a double
double *pointer_to_double;
// declare a double
double my_double = 0.0;
// use the indirection operator (*) to dereference the pointer and get the value
// that it's pointing to.
my_double = *pointer_to_double;
This might be done like so in a real program:
void print_chance_of_snow(double *chance)
{
double d = *chance;
d = d * 100; // convert to a percentage
printf("Chance of snow is: %.2f%%\n", d);
}
int main(int argc, char *argv[])
{
double chance_of_snow = 0.45;
print_chance_of_snow(&chance_of_snow);
}
Related
I am learning C++ using C++ Primer 5th edition. In particular, i read about void*. There it is written that:
We cannot use a void* to operate on the object it addresses—we don’t know that object’s type, and the type determines what operations we can perform on that object.
void*: Pointer type that can point to any nonconst type. Such pointers may not
be dereferenced.
My question is that if we're not allowed to use a void* to operate on the object it addressess then why do we need a void*. Also, i am not sure if the above quoted statement from C++ Primer is technically correct because i am not able to understand what it is conveying. Maybe some examples can help me understand what the author meant when he said that "we cannot use a void* to operate on the object it addresses". So can someone please provide some example to clarify what the author meant and whether he is correct or incorrect in saying the above statement.
My question is that if we're not allowed to use a void* to operate on the object it addressess then why do we need a void*
It's indeed quite rare to need void* in C++. It's more common in C.
But where it's useful is type-erasure. For example, try to store an object of any type in a variable, determining the type at runtime. You'll find that hiding the type becomes essential to achieve that task.
What you may be missing is that it is possible to convert the void* back to the typed pointer afterwards (or in special cases, you can reinterpret as another pointer type), which allows you to operate on the object.
Maybe some examples can help me understand what the author meant when he said that "we cannot use a void* to operate on the object it addresses"
Example:
int i;
int* int_ptr = &i;
void* void_ptr = &i;
*int_ptr = 42; // OK
*void_ptr = 42; // ill-formed
As the example demonstrates, we cannot modify the pointed int object through the pointer to void.
so since a void* has no size(as written in the answer by PMF)
Their answer is misleading or you've misunderstood. The pointer has a size. But since there is no information about the type of the pointed object, the size of the pointed object is unknown. In a way, that's part of why it can point to an object of any size.
so how can a int* on the right hand side be implicitly converted to a void*
All pointers to objects can implicitly be converted to void* because the language rules say so.
Yes, the author is right.
A pointer of type void* cannot be dereferenced, because it has no size1. The compiler would not know how much data he needs to get from that address if you try to access it:
void* myData = std::malloc(1000); // Allocate some memory (note that the return type of malloc() is void*)
int value = *myData; // Error, can't dereference
int field = myData->myField; // Error, a void pointer obviously has no fields
The first example fails because the compiler doesn't know how much data to get. We need to tell it the size of the data to get:
int value = *(int*)myData; // Now fine, we have casted the pointer to int*
int value = *(char*)myData; // Fine too, but NOT the same as above!
or, to be more in the C++-world:
int value = *static_cast<int*>(myData);
int value = *static_cast<char*>(myData);
The two examples return a different result, because the first gets an integer (32 bit on most systems) from the target address, while the second only gets a single byte and then moves that to a larger variable.
The reason why the use of void* is sometimes still useful is when the type of data doesn't matter much, like when just copying stuff around. Methods such as memset or memcpy take void* parameters, since they don't care about the actual structure of the data (but they need to be given the size explicitly). When working in C++ (as opposed to C) you'll not use these very often, though.
1 "No size" applies to the size of the destination object, not the size of the variable containing the pointer. sizeof(void*) is perfectly valid and returns, the size of a pointer variable. This is always equal to any other pointer size, so sizeof(void*)==sizeof(int*)==sizeof(MyClass*) is always true (for 99% of today's compilers at least). The type of the pointer however defines the size of the element it points to. And that is required for the compiler so he knows how much data he needs to get, or, when used with + or -, how much to add or subtract to get the address of the next or previous elements.
void * is basically a catch-all type. Any pointer type can be implicitly cast to void * without getting any errors. As such, it is mostly used in low level data manipulations, where all that matters is the data that some memory block contains, rather than what the data represents. On the flip side, when you have a void * pointer, it is impossible to determine directly which type it was originally. That's why you can't operate on the object it addresses.
if we try something like
typedef struct foo {
int key;
int value;
} t_foo;
void try_fill_with_zero(void *destination) {
destination->key = 0;
destination->value = 0;
}
int main() {
t_foo *foo_instance = malloc(sizeof(t_foo));
try_fill_with_zero(foo_instance, sizeof(t_foo));
}
we will get a compilation error because it is impossible to determine what type void *destination was, as soon as the address gets into try_fill_with_zero. That's an example of being unable to "use a void* to operate on the object it addresses"
Typically you will see something like this:
typedef struct foo {
int key;
int value;
} t_foo;
void init_with_zero(void *destination, size_t bytes) {
unsigned char *to_fill = (unsigned char *)destination;
for (int i = 0; i < bytes; i++) {
to_fill[i] = 0;
}
}
int main() {
t_foo *foo_instance = malloc(sizeof(t_foo));
int test_int;
init_with_zero(foo_instance, sizeof(t_foo));
init_with_zero(&test_int, sizeof(int));
}
Here we can operate on the memory that we pass to init_with_zero represented as bytes.
You can think of void * as representing missing knowledge about the associated type of the data at this address. You may still cast it to something else and then dereference it, if you know what is behind it. Example:
int n = 5;
void * p = (void *) &n;
At this point, p we have lost the type information for p and thus, the compiler does not know what to do with it. But if you know this p is an address to an integer, then you can use that information:
int * q = (int *) p;
int m = *q;
And m will be equal to n.
void is not a type like any other. There is no object of type void. Hence, there exists no way of operating on such pointers.
This is one of my favourite kind of questions because at first I was also so confused about void pointers.
Like the rest of the Answers above void * refers to a generic type of data.
Being a void pointer you must understand that it only holds the address of some kind of data or object.
No other information about the object itself, at first you are asking yourself why do you even need this if it's only able to hold an address. That's because you can still cast your pointer to a more specific kind of data, and that's the real power.
Making generic functions that works with all kind of data.
And to be more clear let's say you want to implement generic sorting algorithm.
The sorting algorithm has basically 2 steps:
The algorithm itself.
The comparation between the objects.
Here we will also talk about pointer functions.
Let's take for example qsort built in function
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
We see that it takes the next parameters:
base − This is the pointer to the first element of the array to be sorted.
nitems − This is the number of elements in the array pointed by base.
size − This is the size in bytes of each element in the array.
compar − This is the function that compares two elements.
And based on the article that I referenced above we can do something like this:
int values[] = { 88, 56, 100, 2, 25 };
int cmpfunc (const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
int main () {
int n;
printf("Before sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
qsort(values, 5, sizeof(int), cmpfunc);
printf("\nAfter sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
return(0);
}
Where you can define your own custom compare function that can match any kind of data, there can be even a more complex data structure like a class instance of some kind of object you just define. Let's say a Person class, that has a field age and you want to sort all Persons by age.
And that's one example where you can use void * , you can abstract this and create other use cases based on this example.
It is true that is a C example, but I think, being something that appeared in C can make more sense of the real usage of void *. If you can understand what you can do with void * you are good to go.
For C++ you can also check templates, templates can let you achieve a generic type for your functions / objects.
For example:
int x = 7 // x is variable name
int* p_x = &x // p_x is a pointer to x
int** pp_x = &p_x // pp_x is a double pointer to x.
Is there a quick way to go from x to pp_x without using a intermediate variable p_x?
EDIT:
Thanks to the comments below I realized that such a thing isn't really possible because without p_x, pp_x would be pointless (No pun intended) because it wouldn't be pointing to anything.
If you are targeting anything above C99 you could use compound literals - like following:
int **pp_x = (int *[1]){(int[1]){7}};
int** pp_x = &p_x //pp_x is a double pointer to x.
It is a pointer to a pointer to x. So you must have p_x in order to have pp_x and you need to maintain p_x all the time you want access x via pp_x.
I have a variable of type double *, which I am initialising to 0 with the line:
double* angle = 0;
I then have a function which takes two variables of type const CCoordinate, and three variables of type double * as parameters. This function takes the values held by the const CCoordinate variables and returns three variables of type double * as returned by calculations performed within the function.
EDIT
The declaration for the function mentioned above is:
int InverseVincenty(const CCoordinate aStartPosition,
const CCoordinate aEndPosition,
double* aDistance,
double* aAngle12,
double* aAngle21);
End Edit
I am now trying to write my own function, which will use this function to calculate the three double * variables, and then perform its own calculation on the double * variables. However, it seems that I am trying to compare the values of doubles with the values of double *, and the compiler is giving me some errors saying that I can't do this...
The kinds of calculation I want to do are things such as:
if((a <= b + 5) || (a >= b -5)){
//do something
}
where a is a double and b is a double*.
The compiler is telling me that it cannot convert from a 'double *' to a 'double', but I'm not trying to convert anything, just trying to compare the values held by both variables... Is this possible at all?
I would have thought that since the pointer is pointing to an address in memory that will hold a value that is of an equivalent data type to the other variable (i.e. double and pointer to a double), that this would be possible?
If not, can anyone suggest another way that I could compare their values?
if((a <= *b + 5) || (a >= *b -5)){
//do something
}
Notice that by doing double* angle = 0;You are not initializing the variable rather its pointer meaning angle will point to 0.
Any attempt to de-reference angle will cause a segmentation fault.
Quoting from your question:
I would have thought that since the pointer is pointing to an address in memory that will hold a value that is of an equivalent data type to the other variable (i.e. double and pointer to a double), that this would be possible?
This is not the case. You correctly say the pointer is pointing to an address in memory that will hold a value that is of an equivalent data type to the other variable. However you need to de-reference the pointer using the * operator to access the values that is pointed.
You might want to look at some introductory guide like: this
b is a pointer so you need to dereference it to get the value.
if((a <= *b + 5) || (a >= *b -5))
You tell us about angle but then never mention it again. The above code requires that b points to a valid memory address.
You can call your functions and retrieve the result as follows.
void test(double *d)
{
*d = 5;
}
double d;
test(&d); // store result in d
Or, using references
void test(double& d)
{
d = 5;
}
double d;
test(d); // store result in d
As with your function signature
int InverseVincenty(const CCoordinate aStartPosition,
const CCoordinate aEndPosition,
double* aDistance,
double* aAngle12,
double* aAngle21);
it looks, that the function will return these three double values via pointer references.
To call the function just provide three double variables
double aDistance;
double aAngle12;
double aAngle21;
and provide their addresses in the function call
InverseVincenty(aStartPosition,aEndPosition,&aDistance,&aAngle12,&aAngle21);
// ^ ^ ^
// Note the address-of operators
afterwards you can go on with your double values as usual.
create a dynamic array
int testSize = 10;
float *spec = new float[testSize];
how do you point to spec which points to the dynamic arary?
I tried this but It didn't work.
float **specPtr;
*specPtr = &spec[0];
float **specPtr;
specPtr = &spec;
spec is a pointer,so spePtr is the pointer that point to spec
Your problem is that by putting the dereference operator operator, you're assigning what the pointer specPtr points to, not what it actually is.
Try this instead
float **specPtr;
specPtr = &spec; // Note the omission of the '*'
I have a function that takes a pointer to a floating point array. Based on other conditions, I know that pointer is actually pointing to a 2x2 OR 3x3 matrix. (in fact the memory was initially allocated as such, e.g. float M[2][2] ) The important thing is I want to make this determination in the function body, not as the function argument.
void calcMatrix( int face, float * matrixReturnAsArray )
{
// Here, I would much rather work in natural matrix notation
if( is2x2 )
{
// ### cast matrixReturnAsArray to somethingAsMatrix[2][2]
somethingAsMatrix[0][1] = 2.002;
// etc..
}
else if(is3x3)
{ //etc...
}
}
I am aware that I could use templates and other techniques to better address this problem. My question is really about how to make such a cast at the ### comment. Working in C++.
float (*somethingAsMatrix)[2] = (float (*)[2]) matrixReturnAsArray;
float * could point to the first element of an array of floats, and ought to be reinterpret_castable to that array type. And the result of that cast could point to the first element of a float [][] and so should be reinterpret_castable to that type, and so on. You ought to be able to compose such casts and just directly do
float (&arr)[2][2] = *reinterpret_cast<float (*)[2][2]>(matrixReturnAsArray);
An argument of the type float ** is not the same and should not be used this way.
To avoid undefined behavior the pointer must originate from an actual multi-dimensional array, and if the float* is used directly you cannot access more than the first row of the multi-dimensional matrix.
void foo(float *f) {
f[3] = 10.;
float (&arr)[2][2] = *reinterpret_cast<float (*)[2][2]>(f);
arr[1][1] = 10.;
}
void main() {
float a[2][2];
foo(&a[0][0]); // f[3] = 10.; is undefined behavior, arr[1][1] = 10. is well defined
float b[4];
foo(&b[0]); // f[3] = 10.; is well-defined behavior, arr[1][1] = 10. is undefined
}
Given float arr[2][2]; nothing guarantees that &arr[0][1] + 1 is the same as &arr[1][0], as far as I have been able to determine. So although you can use a single dimensional array as a multi-dimensional array by doing f[i*width + j] you cannot treat a multi-dimensional array like a single dimensional array.
It's better to use C++'s compile-time type-safety instead of just relying on not accidentally passing the wrong thing or performing the wrong reinterpret_cast. To get type-safety using raw-arrays you should use references to the raw array type you want:
void foo(float (&f)[2][2]) {}
void foo(float (&f)[3][3]) {}
If you want to pass arrays by value you can't use raw arrays and should instead use something like std::array:
void foo(std::array<std::array<float,2>,2> f) {}
void foo(std::array<std::array<float,3>,3> f) {}
This sort of casting is always cleaner, and easier to deal with, with a judicious use of typedef:
typedef float Matrix_t[2][2];
Matrix_t* someThingAsMatrix = (Matrix_t*) matrixReturnAsArray;
If this is C++ and not C, though, you should create a matrix class. (Or better yet, look for an open source one.)
If I am right:
typedef float Matrix_t[2][2];
Matrix_t &matrix = *(Matrix_t *)matrixReturnAsArray;
or
float (&matrix2)[2][2] = *(float ( *)[2][2])matrixReturnAsArray;
In C there is only the way with the pointer
Matrix_t *someThingAsMatrix = (Matrix_t *)matrixReturnAsArray;
and access via:
(*someThingAsMatrix)[1][0] = ...