4
void alloco(int *ppa)
{
    int i;
    printf("inside alloco %d\n",ppa);
    ppa = (int *)malloc(20);
    ppa[15] = 9;
    printf("size of a %d \n", sizeof(ppa));
    for(i=0;i<20;i++)
    printf("a[%d] = %d \n", i, ppa[i]);
}

int main()
{
    int *app = NULL;
    int i;
    printf("inside main\n");
    alloco(app);
    for(i=0;i<20;i++)
    printf("app[%d] = %d \n", i, app[i]);
    return(0);
}

Basically all I wanted to do is to pass a null pointer from my main to a function(alloco) which allocates memory/fills the same location the pointer is pointing to and returns. I am getting local prints correctly that is inside function(alloco) but not in main.

Am I doing anything wrong here?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
pa1
  • 778
  • 3
  • 11
  • 26

2 Answers2

9

C uses pass by value for function parameter passing. You can change the value at address pointed by app [i.e., ppa, in alloco()] from alloco() but cannot change the value of app. In other words, ppa is local to function alloco(). Changing the value of ppa won't be affecting (reflected to) app present in main().

If you want to change the value of app itself from alloco(), you need to pass a pointer to app (Pointer-to-Pointer).

Apart from this issue, in your code

ppa = (int *)malloc(20);  

is wrong. What you wanted is actually

ppa = malloc(20 * sizeof (int)); //argument is in bytes, not in `int` or any elements

or, better,

ppa = malloc(20 * sizeof * ppa);  //data type integrity

Also, it's worthy to mention that please do not cast the return value of malloc() and family in C.

One more thing, while printing a pointer, use %p format specifier, while printing size_t, use %zu, like

printf("inside alloco %p\n",ppa);

and

printf("size of a %zu\n", sizeof(ppa));  //sizeof returns size_t
Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
7

You need this:

void alloco(int **ppa)
{
    int i;
    printf("inside alloco %p\n",ppa);
    *ppa = malloc(20 * sizeof(int));
    (*ppa)[15] = 9;     // rather pointless, in the loop below (*ppa)[15] will be
                        // overwritten anyway
    printf("size of a %d \n", sizeof(*ppa));  // rather pointless, not sure
                                              // what you want to print here

    for(i = 0; i < 20; i++)
      printf("a[%d] = %d \n", i, (*ppa)[i]);
}

int main()
{
    int *app = NULL;  // you can drop the '= NULL', it's useless, because
    int i;            // alloco(&app) will change the value of app anyway
    printf("inside main\n");
    alloco(&app);

    for(i = 0; i < 20; i++)
      printf("app[%d] = %d \n", i, app[i]);

    return 0;
}

In your program you pass a pointer to alloco which will be in the ppa parameter. This ppa parameter is just like a local variable inside of alloco and when you modify it, the original value you passed to the function in main(app) won't be modified.

In the corrected version, we pass a pointer to app. In alloco we dereference that pointer and write the malloced value to it.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • Standard Warning : Please [do not cast](http://stackoverflow.com/q/605845/2173917) the return value of `malloc()` and family in `C`. and some explanation will really do good. :-) – Sourav Ghosh Apr 30 '15 at 11:11
  • hi, i got the logic but when executed i get a core dump. inside main inside allocosize of a 4 a[0] = 0 a[1] = 9 a[2] = -13543595 Segmentation fault (core dumped) – pa1 Apr 30 '15 at 11:20
  • 1
    @Coder: I edited the program, it should be `(*ppa)[15]` instead of `*ppa[15]`. – Jabberwocky Apr 30 '15 at 11:31
  • Use `%p` to print pointers and `%zu` to print a `size_t` here:`printf("inside alloco %d\n",ppa);` and here `printf("size of a %d \n", sizeof(*ppa));` respectively. Crank up the warnings, Michael! – Spikatrix Apr 30 '15 at 11:32
  • @michael Can you explain why is that? :) – pa1 Apr 30 '15 at 11:35
  • 2
    @Coder , Because of operator precedence. You need to dereference the pointer before appyling the `[15]` operator. – Spikatrix Apr 30 '15 at 11:36
  • as well as using the wrong format specifier, `printf("size of a %d \n", sizeof(*ppa));` is not very useful information. There's no way to retrieve how much space was malloc'd. – M.M Apr 30 '15 at 11:38
  • @MattMcNabb , Because it is the same as `printf("size of a %d \n", sizeof(int*));`? – Spikatrix Apr 30 '15 at 11:40
  • @CoolGuy yes that's right – M.M Apr 30 '15 at 11:45