Reputation: 55
Already this question is been asked here: double pointer vs single pointer
I followed the instructions of this above question but facing segfaults and still unable to understand exactly whats happening in the memory (what points to what and how). Below is the code:
#include <stdio.h>
#include <stdlib.h>
void func(int **ptr)
{
*ptr = (int *) malloc (sizeof(int));
**ptr = 10;
printf("Inside func: ptr: %p *ptr: %p **ptr: %p %d\n", ptr, *ptr, **ptr, **ptr);
}
void func2(int *ptr)
{
int i = 10;
ptr = (int *) malloc (sizeof(int));
*ptr = 288;
printf("Inside func2: ptr: %p *ptr: %p %d\n", ptr, *ptr, *ptr);
}
int main()
{
int *a = NULL, *b = NULL;
func(&a);
printf("&a: %p, a: %p, *a: %p *a: %p %d\n", &a, a, *a, *a, *a);
func2(b);
printf("*b: %d\n", *b);
return 0;
}
Output:
main.c:8:51: warning: format ‘%p’ expects argument of type ‘void *’, but argument 4 has type ‘int’ [-Wformat=]
main.c:16:42: warning: format ‘%p’ expects argument of type ‘void *’, but argument 3 has type ‘int’ [-Wformat=]
main.c:23:33: warning: format ‘%p’ expects argument of type ‘void *’, but argument 4 has type ‘int’ [-Wformat=]
main.c:23:40: warning: format ‘%p’ expects argument of type ‘void *’, but argument 5 has type ‘int’ [-Wformat=]
Inside func: ptr: 0x7ffcf5c49760 *ptr: 0x22f7010 **ptr: 0xa 10
&a: 0x7ffcf5c49760, a: 0x22f7010, *a: 0xa *a: 0xa 10
Inside func2: ptr: 0x22f7030 *ptr: 0x120 288
Segmentation fault (core dumped)
In func--> when a & ptr
are assigned & pointing to same memory locations, why cant it happen to func2.
Anyways for *ptr I am passing b (which is the address of *b) and changing the value.
Unable to understand what points to what and how. If someone could help will be very thankful.
Though its a repetition of already asked question, posted since the answer is insufficient for me to understand. Hence pls dont mark is as duplicate atleast until the question is been answered correctly.
Upvotes: 0
Views: 212
Reputation: 1579
Let me put it in different way,
consider an example,
int x;
int *y = &x;
int **z = &y;
x = 10;
Which simplifies to this,
Note: Only for illustration purpose I have chosen address of x,y,z as 0x1000,0x2000,0x3000 respectively.
What is happening in
func1
?
ptr
is local to func1
, *ptr
is same as accessing a
and **ptr
is same as accessing dynamically allocated memory. Dynamically allocated memory is stored to *ptr
i.e to a
.
What is happening in
func2
?
ptr
is local to func2
and point to NULL
on function call func2(b)
. On malloc
, ptr
will hold dynamically allocated memory but doesn't alter b
. On exit of func2
scope memory is leaked(i.e lost the pointer to release the memory).
#include <stdio.h>
#include <stdlib.h>
void func(int **ptr)
{
*ptr = malloc (sizeof(int));
**ptr = 10;
printf("Inside func: ptr: %p *ptr: %p **ptr: %d\n", ptr, *ptr, **ptr);
}
void func2(int *ptr)
{
int i = 10;
ptr = malloc (sizeof(int));
*ptr = 288;
printf("Inside func2: ptr: %p *ptr: %d\n", ptr, *ptr);
}
int main()
{
int *a = NULL, *b = NULL;
func(&a);
printf("&a: %p, a: %p, *a: %d\n", &a, a, *a);
func2(b);
printf("b: %p\n", b);
return 0;
}
output
Inside func: ptr: 0x7ffc75e14030 *ptr: 0x1db0010 **ptr: 10 &a: 0x7ffc75e14030, a: 0x1db0010, *a: 10 Inside func2: ptr: 0x1db0030 *ptr: 288 b: (nil)
Consider Do I cast the result of malloc? in your code.
Upvotes: 1
Reputation: 919
Maybe this helps a little:
int a=20, *pa=&a, **ppa=&pa;
var mem val
a (0x1000) 20
pa (0x2000) 0x1000
ppa (0x3000) 0x2000
ppa == 0x2000
*ppa == 0x1000
**ppa == 20
pa == 0x1000
*pa == 20
**pa not possible
&a == 0x1000
&pa == 0x2000
&ppa == 0x3000
If you call func2(pa)
you call func2(0x1000)
. That's the location of a. So only a is changeable, not pa.
If you call func(ppa)
you call func(0x2000)
. That's the location of pa. So pa and a are changeable not ppa.
Upvotes: 1
Reputation: 483
I try to give you a quick answer...
a single pointer declaration like void func2(int *ptr)
will give you access to the memory location of whatever int value ptr is pointing to.
but if you use void func(int **ptr)
you give the adress of the pointer to the int variable.
You are using func2(b);
without first assigning b (as it is a pointer to an int) a valid adress, something like this:
int an_integer = 13;
int *b = &an_integer;
func2(b); // now it should work
Upvotes: 0
Reputation: 3366
The pointer b
was never initialized, not in main and not in the function. It does not point to any valid memory block.
you can try the following. &b is a pointer to an integer.
int b = 0;
func2(&b);
Upvotes: 1