Preethi
Preethi

Reputation: 55

Single Versus Double pointer in C

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

Answers (4)

TruthSeeker
TruthSeeker

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,

enter image description here

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

Holger
Holger

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

Wolfgang Roth
Wolfgang Roth

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

eyalm
eyalm

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

Related Questions