I have a structure usually containing a pointer to an int. However, in some special cases, it is necessary that this int pointer points to another pointer which then points to an int. Wow: I mentioned the word pointer 5 times so far!
Is this even possible?
I thought about it that way: Instead of using a second int pointer, which is most likely not possible as my main int pointer can only point to an int and not to another int pointer, I could make it a reference like this:
int intA = 1;
int intB = 2;
int& intC = intB;
int* myPointers[ 123 ];
myPointers[ 0 ] = &intA;
myPointers[ 1 ] = &intB;
myPointers[ 3 ] = &intC;
So the above would do what I want: The reference to intB (intC) behaves quite like I want it to (If it gets changed it also changes intB)
The problem: I can't change references once they are set, right? Or is there a way?
Everything in short: How do I get a value to work with * (pointers) and ** (pointers to pointers)?
int* and int** are different types so you can't use one as the other without using a potentially non-portable cast.
In the declaration:
int& intC = intB;
The reference intC will always refer to the int intB. The binding cannot be changed.
You could use a union to support a type that could be either an int* or an int** but you would need to be certain when you're reading, which member of the union is valid at any point.
union PIntOrPPInt
{
int* pint;
int** ppint;
};
int intA;
int intB;
int* pintC = &intB;
PIntOrPPInt myPointers[ 123 ];
myPointers[ 0 ].pint = &intA;
myPointers[ 1 ].pint = &intB;
myPointers[ 3 ].ppint = &pintC;
You could put a pointer to intB in both array elements:
myPointers[ 1 ] = &intB;
myPointers[ 3 ] = &intB;
This way both elements point to the same variable and *myPointers[1] will always be the same as *myPointers[3]. Is this what you want to achieve?
We rarely if ever use pointers to pointers in C++. Instead, like you suggest, we use reference to pointers. That said, C++ is a strongly-typed, static-typed language. So you have to decide at compile-time what your array elements are going to point to.
One approach is to wrap the array elements in a class:
struct P {
P() : p(0) { }
P(int* p) : p(p) { }
P(int** p) : p(*p) { }
operator int*() const { return p; }
int *p;
};
int main(int argc, char* argv[])
{
int *i1 = new int(5);
int **i2 = &i1;
int *&i3 = i1;
P arr[4] = {i1, i2, i3, P()};
delete i1;
return 0;
}
Related
So I know that a pointer is:
int *someNumber;
but I have run accross some code with:
int* pOutputData = nullptr;
byte* pOutputDataByte = nullptr;
What does int* mean?
Is that some kind of array of int? Is it a pointer to the type?
int * and int* are the same thing. The whitespace doesn't change anything.
int * can be used either as a pointer to int or as a pointer to the first element of an array of ints. How a variable is used is context-dependent. Judging by the variable names, I'd guess that someNumber points to a single int and pOutputData points to an array.
Both are same
White space does not mean anything in c
int * num ;
int *num;
int* num;
All the above statements are same!
We use int* as default; mainly in data structure, to avoid confusion.
Always read pointer variables from right to left
int *p means p is a pointer to an int
char *p means p is a pointer to a char
const int *p means p is a pointer to an integer constant
int * const p means p is constant pointer to an int
#include <stdlib.h>
int int_sorter( const void *first_arg, const void *second_arg )
{
int first = *(int*)first_arg;
int second = *(int*)second_arg;
if ( first < second )
{
return -1;
}
else if ( first == second )
{
return 0;
}
else
{
return 1;
}
}
In this code, what does this line mean?
int first = *(int*)first_arg;
I thinks it's typecasting. But, from
a pointer to int
to a
pointer to int
little confused here.
Thanks
?
first_arg is declared as a void*, so the code is casting from void* to int*, then it de-references the pointer to get the value pointed from it. That code is equal to this one:
int first = *((int*) first_arg);
and, if it is still not clear:
int *p = (int *) first_arg;
int first = *p;
It is casting a void pointer to a integer pointer and then dereferencing it.
Let's think about it in steps.
void *vptr = first_arg;
int *iptr = (int *)first_arg; // cast void* => int*
int i = *iptr; // dereference int* => int
So, you're specifying the type of data the pointer points to, and then dereferencing it.
int first = *(int*)first_arg;
It's the same as:
int* ptr_to_int = (int*)first_arg;
int first = *ptr_to_int;
That first line does 2 things: it casts the void pointer to an int* and access that memory location to retrieve the value that's there.
There are already many answers to your question, this is more like a comment, something that you will inevitably learn in your quest on mastering C and C++.
Your function is too long. From its name, I predict what you really need is:
int int_sorter( const void *first_arg, const void *second_arg )
{
return *(int*)first_arg - *(int*)second_arg;
}
I've a little question.
I'm trying to define an array of function pointers dynamically with calloc.
But I don't know how to write the syntax.
Thanks a lot.
The type of a function pointer is just like the function declaration, but with "(*)" in place of the function name. So a pointer to:
int foo( int )
would be:
int (*)( int )
In order to name an instance of this type, put the name inside (*), after the star, so:
int (*foo_ptr)( int )
declares a variable called foo_ptr that points to a function of this type.
Arrays follow the normal C syntax of putting the brackets near the variable's identifier, so:
int (*foo_ptr_array[2])( int )
declares a variable called foo_ptr_array which is an array of 2 function pointers.
The syntax can get pretty messy, so it's often easier to make a typedef to the function pointer and then declare an array of those instead:
typedef int (*foo_ptr_t)( int );
foo_ptr_t foo_ptr_array[2];
In either sample you can do things like:
int f1( int );
int f2( int );
foo_ptr_array[0] = f1;
foo_ptr_array[1] = f2;
foo_ptr_array[0]( 1 );
Finally, you can dynamically allocate an array with either of:
int (**a1)( int ) = calloc( 2, sizeof( int (*)( int ) ) );
foo_ptr_t * a2 = calloc( 2, sizeof( foo_ptr_t ) );
Notice the extra * in the first line to declare a1 as a pointer to the function pointer.
I put a small example here that may help you
typedef void (*fp)(int); //Declares a type of a void function that accepts an int
void test(int i)
{
printf("%d", i);
}
int _tmain(int argc, _TCHAR* argv[])
{
fp function_array[10]; //declares the array
function_array[0] = test; //assings a function that implements that signature in the first position
function_array[0](10); //call the cuntion passing 10
}
You'd declare an array of function pointers as
T (*afp[N])();
for some type T. Since you're dynamically allocating the array, you'd do something like
T (**pfp)() = calloc(num_elements, sizeof *pfp);
or
T (**pfp)() = malloc(num_elements * sizeof *pfp);
You'd then call each function as
T x = (*pfp[i])();
or
T x = pfp[i](); // pfp[i] is implicitly dereferenced
If you want to be unorthodox, you can declare a pointer to an array of pointers to functions, and then allocate that as follows:
T (*(*pafp)[N])() = malloc(sizeof *pafp);
although you would have to deference the array pointer when making the call:
x = (*(*pafp)[i])();
typedef R (*fptr)(A1, A2... An);
where R is the return type, A1, A2... An are the argument types.
fptr* arr = calloc(num_of_elements,sizeof(fptr));
Assuming all your functions are of type void ()(void), something like this
typedef void (*fxptr)(void);
fxptr *ptr; // pointer to function pointer
ptr = malloc(100 * sizeof *ptr);
if (ptr) {
ptr[0] = fx0;
ptr[1] = fx1;
/* ... */
ptr[99] = fx100;
/* use "dynamic array" of function pointers */
free(ptr);
}
I know that converting a pointer to one int is unsafe, because the pointer can be bigger than the int in some architectures (for instance in x86_64).
But what about converting the pointer to several ints, an array of them? If the pointer size is 2 times bigger than int then convert pointer* to int[2].
The number of needed ints then is ceil(sizeof(pointer*)/sizeof(int)).
I need to do this because there is a function which takes ints as arguments and I want to pass a pointer to it.
Doesn't your platform provide a intptr_t ?
Fairly robust & portable:
void* p = foo();
std::vector<int> buf(sizeof(p));
std::copy(reinterpret_cast<char*>(&p),
reinterpret_cast<char*>(&p) + sizeof(p),
buf.begin());
What about something like this:
void *pointer = (void*) 0x0123456789ABCDEFULL;
// 4 int's max, I don't know how to do it in a generic way
assert(sizeof(pointer) <= 4*sizeof(int));
int buffer[4]; // copy from pointer to buffer
memcpy(buffer, &pointer, sizeof(pointer));
// call the function
f(buffer[0], buffer[1], buffer[2], buffer[3]);
// how to recover the value of the pointer
void f(int b0, int b1, int b2, int b3) {
int buffer[4] = {b0, b1, b2, b3};
void *pointer; // copy from buffer to pointer
memcpy(&pointer, buffer, sizeof(test_pointer));
}
I can't think of a reason to do it like that, but thats up to you :).
Usually you should not do that in a generic way, so what I'd do is, coding the 2 or 3 ways the pointer has to be transformed.
if( sizeof(pointer) == sizeof(int16) ) //or short
{
transformShortToInt(pointer);
}
else if( sizeof(pointer) == sizeof(Int32) )
{
(int)pointer;
}
else if( sizeof(pointer) == sizeof(Int64) )
{
int[2] ar = new int[2];
ar[0] = (int)(pointer & 0x0000FFFF);
ar[1] = (int)((pointer>>32) & 0x0000FFFF);
}
Although the generic code would also not be that complex.
edit: generic:
int arSize = sizeof(pointer)/sizeof(int);
if(arSize < 1)
{
arSize = 1;
}
int[] args = new int[arSize];
for( int i = 0; i < arSize; i++ )
{
args[i] = (int)((pointer>>(i*32))&0x0000FFFF);
}
although I did not test what happens with pointer >> 0 i guess it should work :).
Yet another solution:
#define BIG_ENOUGH 4
typedef union {
int buffer[BIG_ENOUGH];
pointer_t* pointer;
} proxy_t;
static_assert(sizeof(pointer_t*) <= BIG_ENOUGH*sizeof(int));
// before calling the function
proxy_t proxy;
proxy.pointer = the_pointer;
// call to the function, cannot be generic here
f(proxy.buffer[0], proxy.buffer[1], proxy.buffer[2], proxy.buffer[3]);
// how to recover the value of the pointer
void f(int b0, int b1, int b2, int b3) {
proxy_t proxy = { { b0, b1, b2, b3 } };
the_pointer = proxy.pointer;
}
if a function takes an array of ints, then yes you can manually detect the size of void* versus the size of int on your machine and save your pointer to array[0] + array[1], etc.
It's a bit hard to tell what's really needed from your description. What will the function do? Will you have to handle big/little-endian difference, for example?
I have macros for this:
#define DIM_ARR(arr) (sizeof(arr) / sizeof(arr[0]))
Even if array is empty - this construction (sizeof(arr[0])) resolved on compile time - that is why you will get correct size
you said you want to pass a pointer to a function with int as arguments.
If your pointer points to an integer or character or float you can always dereference it, caste it and pass by value.
Or, if you really want to pass by address, then modify the function definition to take pointer as argument.
Or, if you are using some library function then you are on the wrong way man.
And even you convert it to an array of ints, how are going to pass the array?, array are always passed by address.
If you write a C++ function like
void readEmStar( int *arrayOfInt )
{
}
vs a C++ function like:
void readEmSquare( int arrayOfInt[] )
{
}
What is the difference between using [square brackets] vs *asterisk, and does anyone have a style guide as to which is preferrable, assuming they are equivalent to the compiler?
For completeness, an example
void readEmStar( int *arrayOfInt, int len )
{
for( int i = 0 ; i < len; i++ )
printf( "%d ", arrayOfInt[i] ) ;
puts("");
}
void readEmSquare( int arrayOfInt[], int len )
{
for( int i = 0 ; i < len; i++ )
printf( "%d ", arrayOfInt[i] ) ;
puts("");
}
int main()
{
int r[] = { 2, 5, 8, 0, 22, 5 } ;
readEmStar( r, 6 ) ;
readEmSquare( r, 6 ) ;
}
When you use the type char x[] instead of char *x without initialization, you can consider them the same. You cannot declare a new type as char x[] without initialization, but you can accept them as parameters to functions. In which case they are the same as pointers.
When you use the type char x[] instead of char *x with initialization, they are completely 100% different.
Example of how char x[] is different from char *x:
char sz[] = "hello";
char *p = "hello";
sz is actually an array, not a pointer.
assert(sizeof(sz) == 6);
assert(sizeof(sz) != sizeof(char*));
assert(sizeof(p) == sizeof(char*));
Example of how char x[] is the same as char *x:
void test1(char *p)
{
assert(sizeof(p) == sizeof(char*));
}
void test2(char p[])
{
assert(sizeof(p) == sizeof(char*));
}
Coding style for passing to functions:
It really doesn't matter which one you do. Some people prefer char x[] because it is clear that you want an array passed in, and not the address of a single element.
Usually this is already clear though because you would have another parameter for the length of the array.
Further reading:
Please see this post entitled Arrays are not the same as pointers!
C++ Standard 13.1.3
— Parameter declarations that differ
only in a pointer * versus an array []
are equivalent. That is, the array
declaration is adjusted to become a
pointer declaration (8.3.5). Only the
second and subsequent array dimensions
are significant in parameter types
(8.3.4). [Example:
int f(char*);
int f(char[]); // same as f(char*);
int f(char[7]); // same as f(char*);
int f(char[9]); // same as f(char*);
int g(char(*)[10]);
int g(char[5][10]); // same as g(char(*)[10]);
int g(char[7][10]); // same as g(char(*)[10]);
int g(char(*)[20]); // different from g(char(*)[10]);
—end example]
There is no difference between your two codes, apart from the different style obviously. In both cases the array is passed by reference and not by value, as function parameters type *x and type x[] are semantically the same.
On the style question I'll stick my neck out and say int *arrayOfInt is better. Which ever syntax you use you are passing a pointer and the type should make that clear.
This is just my opinion.
The two expressions are equivalent. They each evaluate to the address of the first element of the array arrayOfInt.