Dereferencing a double pointer - c

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;
}

Related

What does **p mean in c? [duplicate]

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.

Pointer to pointer in c source file

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.

why * double pointer value is same with * pointer array?

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;
}

Printing out the value pointed by pointer (C Programming)

I would like to print out the contents a pointer pointing to. Here is my code:
int main(){
int* pt = NULL;
*pt = 100;
printf("%d\n",*pt);
return 0;
}
This gives me a segmentation fault. Why?
These lines:
int* pt = NULL;
*pt = 100;
are dereferencing a NULL pointer (i.e. you try to store value 100 into the memory at address NULL), which results in undefined behavor. Try:
int i = 0;
int *p = &i;
*p = 100;
Because you are trying to write to address NULL.
Try:
int main(){
int val = 0;
int* pt = &val;
*pt = 100;
printf("%d\n",*pt);
return 0;
}

C - malloc array in function and then access array from outside

Here is how I malloc an int var and then access this var outside of the function
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int * a;
f1(&a);
printf("%d\n", *a);
// keep it clean :
free(a);
return 0;
}
Using same logic above, how do I malloc a 1 dim array inside a function and then access it outside of the func?
Please help, I am bit confused with pointers to array.
In exactly the same way but with some different arithmetic. You can think of what you are doing now as allocating an array with one element. Just multiply sizeof(int) by the number of elements you want your array to have:
int f1(int ** b, int arrsize) {
*b = malloc(sizeof(int) * arrsize);
// then to assign items:
(*b)[0] = 0;
(*b)[1] = 1;
// etc, or you can do it in a loop
}
int main() {
int * a, i;
int size = 20;
f1(&a, size); // array of 20 ints
for (i = 0; i < size; ++i)
printf("%d\n", a[i]); // a[i] is the same as *(a + i)
// so a[0] is the same as *a
// keep it clean :
free(a);
return 0;
}
(untested, but I believe it'll work)
int f1(int ** b) {
*b = malloc(sizeof(int)*4);
(*b)[0] = 5;
(*b)[1] = 6;
(*b)[2] = 7;
(*b)[3] = 8;
}
int main() {
int * a;
f1(&a);
printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]); // should be "5 6 7 8"
// keep it clean :
free(a);
return 0;
}
You are almost there *b = malloc(sizeof(int)); allocates space for a single int ( a bit pointless since the pointer is at least as big as this)
The more normal usage is *b = malloc(number_of_ints*sizeof(int));
Remember that the [] syntax just does the array maths for you (a+10) and a[10] point to exactly the same thing memory location, so you can allocate it using malloc, pass the poitner and refer to it as an array.
The only things about arrays and pointers that is complicated (apart from remembering when to use * and &) is that malloc() works in bytes, so you need to tell it the sizeof an int. But the int * it returns knows about ints so to get to the next value you only need to do a++ or a+1 or a[1] even though it is really 4 or 8 bytes different in value.
Instead of malloc()ing a single int, malloc the array.
int f1(int * b) {
b = malloc(ARRAY_LENGTH * sizeof(int));
*b = 5;
b[1] = 6;
*(b + 2) = 7;
}
You'll want to use a calloc call instead of malloc (See this: http://www.manpagez.com/man/3/calloc/)

Resources