for example in this code:
double **Data, *DataT;
Data = (double **)malloc(3*sizeof(double *)+3*12*sizeof(double));
I just read that malloc allocates memory from the heap. But i could not find what that (double **) meant in front of the malloc.
There is a line of code directly after this as well that i have seen this in.
for (i = 0, DataT = (double *)(Data+3); i < 3; i++, DataT += 12)
Here there is a (double *) in front of Data+3
Could you please explain to me what that does?
Thank you
malloc() returns type void *, while your pointer is of type double * or double **. The operator before malloc - looking like (type) - is the type conversion operator, needed to convert malloc's return value to the type of the pointer you are using.
(double**) is a cast. it says that the result of the malloc is changed to double**.
malloc returns void* according to the standard.
so it is casted to double** to be the same nature of data : double**.
but in C, there is no need to the cat because void * is casted implicitly. so you can write directly :
Data = malloc(3*sizeof(double *)+3*12*sizeof(double));
as your question is for C++, which is compatible with C malloc, you have to put the cast : (double**).
so you can use malloc and the cast if you have a code that you want to use in programs in C and in C++. else, use new and delete...
It's a type cast. The rules for its syntax and usage should be a part of any C primer. The definitive book for this kind of thing is the one by Kernighan and Ritchie.
It means "pointer to a pointer".
The (double **) is a casting operator. It casts the void pointer returned by malloc to a pointer to pointer to double.
It's a pointer to a pointer. e.g. a double dereference.
c -> some memory address
*c -> whatever is at the memory address stored in c
**c -> whatever is at the memory address stored in *c
The (double**) and (double*) are what are known as C style casts. These make whatever type is after them into the type inside the parentheses.
The first C style cast is turning the return type of malloc into double** so it can be stored in the double** variable.
The second cast is turning it into a double*, so it can be dereferenced correctly.
double** means that you're allocating a pointer to a pointer of a double
Related
I was searching how to create an array of pointers and copy it to CUDA memory. I found this post CUDA Double pointer memory copy but the following line in the accepted answer
int ** devicePointersStoredInDeviceMemory;
cudaMalloc( (void**)&devicePointersStoredInDeviceMemory, sizeof(int*)*N);
is bugging me a bit.
What's the meaning of passing the address of a double pointer and cast it to a void**?
Wouldn't &devicePointerStoredInDeviceMemory be the same as int*** so why cast it to void** instead of void***?
It works, but I do not understand why.
What's the meaning of passing the address of a double pointer and cast it to a void**? Wouldn't &devicePointerStoredInDeviceMemory be the same as int*** so why cast it to void** instead of void***?
The cudaMalloc function takes a void ** as its first parameter, so if we're going to call cudaMalloc, that's the type we need. The purpose of the first parameter is to tell codaMalloc where to store the pointer to the memory we allocated.
You could do this just as well:
void *j;
cudaMalloc(&j, sizeof(int*)*N); // stores result in j
int **devicePointersStoredInDeviceMemory = (int **) j;
Because I followed a discussion where was told "Aliasing through incompatible pointer types is undefined behavior" (e.g. double d; int *p = (int *)&d; following question:
Is it allowed to cast an (double *) to (double **), e.g. double *d1; double **d2 = &d2 and using syntax like d2[0][y] expecting to be the same as d1[y]?
I know that it is not exactly aliasing through incompatible pointer types, but however I am not sure. Background is that I want to have a function which operates on 2-dimensional arrays (= images) but I want to be able to pass only a row or column of an image.
double** is incompatible with double*. The conversion is legal, but the only thing you can do with the results is cast it back. This seems more or less obvious: on a 32 bit machine, a double* won't even have the same size as a double.
But your example doesn't convert a double* to double**. It creates a new double**, which points to the double*. This is fine.
Is it allowed to cast an (double ) to (double *), e.g. double *d1; double **d2 = &d2 and using syntax like d2[0][y] expecting to be the same as d1[y]?
Of course not, and it won't even compile.
But if you meant:
double *d1;
double **d2 = &d2;
then yes, the above is perfectly valid and since d2[0][y] can be seen as (*d2)[y], there's really no problem at all.
Finally, remember that in the above code, you are not casting anything: &d2 is already of type double**. If you have to cast something, please use C++ style casts (static_cast, dynamic_cast, reinterpret_cast, etc..) and not C style casts.
Say I have an object:
void *tmpValue;
and say I know that tmpValue points to a double.
A way to cast this into a double is to do the following:
double* dblPtr = (double*) tmpValue;
double dbl = *dblPtr;
But why does a direct casting from void* to double not work?
double dbl = (double) tmpValue; //error: "cannot convert from 'void*' to 'double'
Thanks in advance.
Interpreting a pointer (a memory address) as a floating-point value is not a sensible operation, and it probably fails on your platform because void * and double are not even the same size.
What you want to do is interpret the pointer as double * and dereference that double * pointer, as in your second code snippet.
You can do this in one line:
double dbl = *(double *)tmpValue;
But, hey, this is C++. Better to do
double dbl = *static_cast<double *>(tmpValue);
You can't cast from a pointer type to double. Recall that pointer type is essentially a memory address (typically 4 bytes containing location information of the data on the memory). Hence you can cast pointer type to integer, but casting to double wouldn't make sense.
When you cast the void* pointer into double* pointer type, you are essentially saying "this is now an address of a double rather than an address of void*"
If you want to get the value as double in one liner nevertheless, you can do
double dbl = *( (double*) tmpValue );
double dbl = *(double*)tmpValue
dereference the pointer and cast ist value
If I have the following pointer variable declarations:
int *a;
int **c;
Regarding to the type and what values each will hold, will it be as follows:
a is of type int*, and will hold a memory address
*a is of type int, and will hold the value of the variable the pointer is pointing to
c is of type int**, and will hold ?????????????????????
c* is of type int*, and will hold the memory address of the pointer it is pointing at
c** is of type int, and assuming that pointer c is pointing to pointer b, and pointer b is pointing to variable a, here, the value held will be the value of the variable a
Is it correct this way, except c which I'm not sure about?
Thanks.
int *a;
int **c;
You are correct about a. It is more common to say a holds a pointer to int.
c is of type int** and will hold a pointer to a pointer to int.
*c is of type int*, and will hold a pointer to int.
**c is of type int, and will hold an integer value. You are correct about c pointing to b and b pointing to a.
See cdecl for some help. :)
c is of type int**, and will hold ?????????????????????
'c' also holds a memory address, just as 'a' does. The difference is that 'c', when dereferenced, will return another memory address. You're just adding another level of indirection.
In your example, c will hold a pointer to an int*; that is, c is a pointer to a pointer. It can be used for multidimensional arrays (like matrices) and it can be used as a function parameter to change a user's int*.
-- a is of type int*, and will hold a memory address
Correct
-- *a is of type int, and will hold the value of the variable the pointer is pointing to
Not exactly: *a will be a reference to the variable the adress points to. You see this when trying *a = 8; and int * x = &(*a)).
If it was a value you couldn't change it. But since it is a reference the value is "routed" to the original place...in this case the memory a points to.
-- c is of type int**, and will hold ?????????????????????
c holds a memory address pointing to a memory address pointing to an int.
*c holds a reference to a memory adress pointing to an int. So you can do: *c = a;
**c is the same as *a.
Every pointer holds memory address. In this case, c is a pointer to int* so, it will hold a memory address of such a variable.
Often, double pointers are used to create dynamic multiarrays in C. You can see it here
C is of type int*. As evident from that, it will hold a data of type int* which in itself is a memory address.
This concept is called far pointer and there can be multiple far pointers up to a certain limit.
Like int** c, you can also have int*** d point to int** c. This is like a queue with every pointer pointing to the next pointer and the front having the data as the actual variable.
The simplest thing that I can think of is playing with spaces. The compiler does not really care, but it makes reasoning easier due to the fact that the syntax of declarations and the usage are the same (by design):
Given:
int ***a; // declaration
int*** a; // type of a is an int*** (read: pointer to pointer to pointer to int)
int** *a; // the type of the object pointed by a (*a) is int**
int* **a; // the type of **a is int*
int ***a; // the type of ***a is int
Disclaimer: this is with respect to data types. Whether you can or not dereference a pointer at runtime is a different issue (has it been initialized, does it point to valid memory...?)
When I try to use a static_cast to cast a double* to an int*, I get the following error:
invalid static_cast from type ‘double*’ to type ‘int*’
Here is the code:
#include <iostream>
int main()
{
double* p = new double(2);
int* r;
r=static_cast<int*>(p);
std::cout << *r << std::endl;
}
I understand that there would be problems converting between a double and an int, but why is there a problem converting between a double* and an int*?
You should use reinterpret_cast for casting pointers, i.e.
r = reinterpret_cast<int*>(p);
Of course this makes no sense,
unless you want take a int-level look at a double! You'll get some weird output and I don't think this is what you intended. If you want to cast the value pointed to by p to an int then,
*r = static_cast<int>(*p);
Also, r is not allocated so you can do one of the following:
int *r = new int(0);
*r = static_cast<int>(*p);
std::cout << *r << std::endl;
Or
int r = 0;
r = static_cast<int>(*p);
std::cout << r << std::endl;
Aside from being pointers, double* and int* have nothing in common. You could say the same thing for Foo* and Bar* pointer types to any dissimilar structures.
static_cast means that a pointer of the source type can be used as a pointer of the destination type, which requires a subtype relationship.
Floating point-to-integer conversion is supported, so int a = static_cast<int>(5.2) is fine. However, it's a conversion - the underlying data types are completely incompatible. What you're asking is for the runtime to convert a pointer to an 8-byte structure to a pointer to a 4-byte structure, which it can't do in any meaningful way.
That having been said, if you really want to interpret your double as an integer, int* r = reinterpret_cast<int*>(p) will work fine.
You can convert between a double and an int with static_cast<>, but not between pointers to different types. You can convert any pointer type to or from void * with static_cast<>.
The rationale may be that int * and double * are often effectively arrays, and the implementation doesn't know how big the array is.
Because you used double * instead of double
The * after it means that you are declaring a pointer, which is vastly different from a regular double.
C++ can not safely static_cast a pointer to a different type of pointer like that.
If you are wanting to do this kinda thing, you must first dereference the variable.
r=new int(static_cast<int>(*p));
You must use new because a double and an integer can not reside in the same memory space(sanely)