I have a question with double pointer to pointer array.
I couldn't understand why is *double_pointer value same with *pointer_array value.
I thought maybe there's something with this line, 'int **pptr = ptr'.
why isn't it 'int **pptr = &ptr' ?
Please help me..
#include <stdio.h>
int main(){
// doulble pointer with array.
int arr[4] = {1,2,3,4};
int *pt = arr;
int **ppt = &pt;
printf("%p, %d\n", *ppt, *pt);
// The result is different. *ppt != *pt
// double pointer with pointer array.
int ptr1[4] = {1,2,3,4};
int ptr2[4] = {5,6,7,8};
int ptr3[4] = {9,10,11,12};
int * ptr[3] = {ptr1, ptr2, ptr3};
int ** pptr = ptr;
// Why is it ptr? I thought it should be &ptr.
printf("%p, %p\n", *pptr, *ptr);
// The result is same. *pptr = *ptr
// Why *pptr is the address of ptr1? It thought should be the address of ptr.
return 0;
}
Related
This question already has answers here:
Why use double indirection? or Why use pointers to pointers?
(18 answers)
Closed 1 year ago.
I know that int *p is a pointer but what does int **p mean exactly? What type of value is that? When I say now p= something, how is that working? I am seeing this in the creation of two-dimensional arrays with pointers.
In short, int **p; is a pointer to a pointer to an int. So, for example:
int i, j; // Integers;
int *p = &i; // Pointer to i
*p = 1; // i is now 1
int *q = &j; // Pointer to j
int **s = &p; // Pointer to p
**s = 2; // i is now 2
s = &q; // s now points to q (pointing to j)
**s = 16; // j is now 16
s = &p; // s now points to p (pointing to i)
**s = 3; // i is now 3
p = &j; // p now points to j
**s = 17; // j is now 17
One use case for a pointer to pointer could be a function which needs to output a pointer to an int and return a success/failure status:
#include <stdbool.h>
bool getIntHandle(unsigned handleId, int **handle)
{
static int handles[] = {12, 23, 34, 45};
bool success = (handleId < sizeof(handles)/sizeof(handles[0])); // Check that handleId is in range
if(success)
{
*handle = &handles[handleId];
}
return success;
}
int main(void)
{
int *handle;
bool success = getIntHandle(2, &handle); // Get a pointer to the integer at index 2
printf("*handle = %d\n", *handle);
return 0;
}
p is a pointer to a pointer to an int. It's the type int **p and the variable p stores an address.
Here is an example of its use. p is an array of two integer pointers. The first of the pointers p[0] points to an array of 3 integers, and the 2nd to an array of 4 integers (combined this is known as ragged array):
#include <stdio.h>
#include <stdlib.h>
int main() {
int **p = malloc(2 * sizeof(int *));
printf("p = %p\n", p);
p[0] = malloc(3 * sizeof(int));
printf("p[0] = %p\n", p[0]);
p[0][0] = 0;
p[0][1] = 1;
p[0][2] = 2;
p[1] = malloc(4 * sizeof(int));
printf("p[1] = %p\n", p[1]);
p[1][0] = 3;
p[1][1] = 4;
p[1][2] = 5;
p[1][3] = 6;
free(p[0]);
free(p[1]);
free(p);
return 0;
}
The most common use, however, is with a regular 2d array that is passed to a function which degrades to a pointer to a pointer.
I see a code which says the following.
typedef struct dummy
{
int a;
int b[100];
} dummy_t;
typedef struct dummya
{
int a;
int b;
} dummya_t;
void * getptr(){
// return a pointer of a memory
}
void function(){
dummya_t*dstptr = getptr();
dummy_t *srcpt = (dummy_t*)(dstptr->b);
}
I can see dummy_t *srcpt = (dummy_t*)(dstptr->b); meaning as a pointer is pointing to another pointer but then *srcpt should be a double pointer right? Like **srcpt
Your code is not correct, you can not cast nor assign using pointers to objects of different types, for example:
struct a { int a, b; };
struct b { int a, b; };
are different objects even having the same members.
struct a x = {.a = 1, .b = 2};
struct b *y = &x; // wrong
I can see dummy_t srcpt = (dummy_t)(dstptr->b); meaning as a pointer
is pointing to another pointer but then *srcpt should be a double
pointer right? Like **srcpt
Your assumptions are not correct, a basic example using plain pointers to int:
#include <stdio.h>
int main(void)
{
int arr[] = {1, 2};
int *a = &arr[0];
int *b = &arr[1];
printf("a = %d b = %d\n", *a, *b);
int **ptr;
ptr = &a;
*ptr = &arr[1];
ptr = &b;
*ptr = &arr[0];
printf("a = %d b = %d\n", *a, *b);
return 0;
}
The output is:
a = 1 b = 2
a = 2 b = 1
As you can see, you use a double pointer (**ptr) when you want to change the contents of a or b (the address where it points to), a more useful example:
#include <stdio.h>
void swap(int **a, int **b)
{
int *temp = *a;
*a = *b;
*b = temp;
}
int main(void)
{
int arr[] = {1, 2};
int *a = &arr[0];
int *b = &arr[1];
printf("a = %d b = %d\n", *a, *b);
swap(&a, &b);
printf("a = %d b = %d\n", *a, *b);
return 0;
}
Same output:
a = 1 b = 2
a = 2 b = 1
I can see dummy_t *srcpt = (dummy_t*)(dstptr->b); meaning as a pointer is pointing to another pointer but then *srcpt should be a double pointer right? Like **srcpt
No. That line means "treat the value of dstptr->b as though it were a value of type dummy_t *, and assign it to srcpt". It's not a pointer to a pointer.
The expression dstptr->b has type int, which cannot be directly assigned to a pointer type. (dummy_t *) is a cast, which tells the compiler to convert the type.
Like Vlad says in his comment, this code doesn't make any sense. It may compile, but just because it compiles doesn't mean it's right.
#include <stdio.h>
#include <stdlib.h>
int* CreateArray(int length){
int arr[length];
int i;
for(i=0; i < length; ++i){
arr[i] = -25;
int* ptr = &arr[i];
printf("%p \n",ptr);
printf("%d \n",*ptr);
}
printf("%d \n",arr[0]);
int* location = &arr;
return location;
}
void main()
{
int* arr = CreateArray(10);
printf("pointer here is %p \n",arr);
int num = *arr;
printf("%d",num);
}
when i run the program i want num to be equal to arr[0] which was declared in the function but it doesn't do that for some reason
The array arr is local to the function CreateArray and not marked as static, so it will deleted on returning from the function and cannot be used after that.
To avoid this, you should allocate arrays dynamically.
Also note that &arr is int(*)[length], so it is not good to assign that to a variable of type int*.
int* CreateArray(int length){
int *arr = malloc(sizeof(*arr) * length); /* allocate dynamically */
if (arr == NULL) exit(1); /* check if allocation succeeded */
int i;
for(i=0; i < length; ++i){
arr[i] = -25;
int* ptr = &arr[i];
printf("%p \n",(void*)ptr); /* void* should be passed for %p */
printf("%d \n",*ptr);
}
printf("%d \n",arr[0]);
int* location = arr; /* assign arr, not &arr */
return location;
}
Your function is returning a pointer created inside the function, and it will be deinitialized when the function is popped from the stack. This is called dangling pointer.
If you want to return a pointer, you have to create it on the heap:
int* arr = malloc(sizeof(*arr) * length);;
But pay attention, now you have to manage the garbage!
I've been trying to increment array of pointers to and assigning them to be addresses of an array but I can't seem to figure it out.
Input:
void * myParam(unsigned int *argv[]){
for(unsigned int i = 0; i < 5; i++){
printf("Block[%d] = Pointer Address %x\n", i, *(argv + i));
}
return *argv;
}
int main(){
unsigned int arr[5] = {1,2,3,4,5};
unsigned int *ptr;
ptr = arr;
ptr = myParam(&ptr);
}
Output:
Block[0] = Pointer Address ea6d6b60
Block[1] = Pointer Address 1
Block[2] = Pointer Address 3
Block[3] = Pointer Address 5
Block[4] = Pointer Address f6770089
You don't have an array of pointers. You have a pointer to one pointer (=an array of one pointer).
Subscripting that argv with anything but 0 (or 1 if you don't dereference that) is undefined. After you dereference it once, you can add 0 through 4 (and possibly dereference those to obtain the array values (1 through 5)).
#include <stdio.h>
void * myParam(unsigned int *argv[]){
for(unsigned int i = 0; i < 5; i++){
printf("Block[%u] = Pointer Address %p, value=%u\n", i, (void*)(*argv + i),
(*argv)[i]);
}
return *argv;
}
int main(){
unsigned int arr[5] = {1,2,3,4,5};
unsigned int *ptr;
ptr = arr;
ptr = myParam(&ptr);
}
I have code snippet that I can't understand how it works, because of one line that does a double dereference. The code looks like this:
void afunction(int**x){
*x = malloc(2 * sizeof(int));
**x = 12;
*(*x + 1) = 13;
}
int main(){
int *v = 10;
afunction(&v);
printf("%d %d\n", v[0], v[1]);
return 1;
}
I understand that the first element of the pointer to pointer gets the value 12, but the line after that I just can't seem to understand. Does the second element in the first pointer get value 13?
The code is rather easy to understand if you use a temporary variable, eg:
void afunction(int**x)
{
int* t = *x;
t = malloc(2 * sizeof(int));
*t = 12;
*(t+1) = 13;
}
so:
x is a pointer to a pointer to int
*x yields a int* (pointer to int)
**x = is like *(*x) = so you first obtain the pointer to int then by dereferencing you are able to set the value at the address
The last part *(*x+1) = can be broken down:
int* pointerToIntArray = *x;
int* secondElementInArray = pointerToIntArray + 1;
*secondElementInArray = 13;
The purpose of using a pointer to pointer here is that you can pass the address to an int* to the function and let the function allocate the memory and fill it with data. The same purpose could be done by returning an int*, eg:
int* afunction() {
int* x = malloc(sizeof(int)*2);
*x = 12;
*(x+1) = 13;
return x;
}
int main() {
int* v = afunction();
return 0;
}