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;
}
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 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;
}
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;
}
I have a C program
#include<stdio.h>
void f(const int* p)
{
int j;
p = &j;
j = 10;
printf("Inside function *p = %d\n",*p);
*p = 5;
printf("Inside function *p = %d\n",*p);
j = 7;
printf("Inside function *p = %d\n",*p);
}
int main()
{
int i = 20, *q = &i;
f(q);
}
Compilation of the program gives the error
Assignment of the read only location *p
at the line *p = 5;
Why is that the assignment j = 10; is valid and *p = 5; is an error.
const int *p means that you can't modify the integer that p is pointing to using p, as in *p = 5;. The integer it points to may not be a const int, which is why j = 10 works. This prevents coders from modifying integer being pointed to.
const int* p mean you can not change the content in the address of p
which is you can not chanage *p
const int mean , its value remain same until program ends so you can not change its value.
The following code gives a segmentation fault. I am not able to figure out as to why. Please see..
#include <stdio.h>
#include <stdlib.h>
int main()
{
int **ptr;
int *val;
int x = 7;
val = &x;
*ptr = (int *)malloc(10 * sizeof (*val));
*ptr[0] = *val;
printf("%d\n", *ptr[0] );
return 0;
}
on debugging with gdb, it says:
Program received signal SIGSEGV, Segmentation fault.
0x0804843f in main () at temp.c:10
*ptr = (int *)malloc(10 * sizeof (*val));
Any help regarding the matter is appreciated.
int **ptr;
*ptr = (int *)malloc(10 * sizeof (*val));
First statement declares a double pointer.
Second dereferences the pointer. In order that you are able to dereference it the pointer should point to some valid memory. it does not hence the seg fault.
If you need to allocate enough memory for array of pointers you need:
ptr = malloc(sizeof(int *) * 10);
Now ptr points to a memory big enough to hold 10 pointers to int.
Each of the array elements which itself is a pointer can now be accessed using ptr[i] where,
i < 10
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int **ptr;
int x;
x = 5;
ptr = malloc(sizeof(int *) * 10);
ptr[0] = &x;
/* etc */
printf("%d\n", *ptr[0]);
free(ptr);
return 0;
}
See the below program, perhaps, it helps to understand better.
#include<stdio.h>
#include <stdlib.h>
int main(){
/* Single Dimention */
int *sdimen,i;
sdimen = malloc ( 10 * sizeof (int));
/* Access elements like single diminution. */
sdimen[0] = 10;
sdimen[1] = 20;
printf ("\n.. %d... %d ", sdimen[0], sdimen[1]);
/* Two dimention ie: **Array of pointers.** */
int **twodimen;
twodimen = malloc ( sizeof ( int *) * 10);
for (i=0; i<10; i++) {
twodimen[i] = malloc (sizeof(int) * 5);
}
/* Access array of pointers */
twodimen[0][0] = 10;
twodimen[0][3] = 30;
twodimen[2][3] = 50;
printf ("\n %d ... %d.... %d ", twodimen[0][0], twodimen[0][3], twodimen[2][3]);
return 0;
}
Hope this helps.. ;).
Conceptually if you are using **ptr, then you need to alloacte memory for ptr & *ptr to defrence **ptr.
But in you case you are alloacting memory only for *ptr,if your compiler is smart enough
its alloacting memory for ptr(one pointer location) to link *ptr,hence it could able to link ptr->ptr->*ptr.Hence you are not getting Seg Fault.
include
include
int main()
{
int **ptr;
int *val;
int x = 7;
val = &x;
ptr = (int**)malloc(sizeof(int**));
*ptr = (int *)malloc(10 * sizeof (*val));
*ptr[0] = *val;
printf("%d\n", *ptr[0] );
return 0;
}
Above would work.
You can find the difference and understand the reason as well.
Bottom line you were de-referencing **ptr without allocating memory to it.