[comp.lang.c] Simple ptr passing question

ric@ace.sri.com (Richard Steinberger) (05/14/91)

	I am a bit rusty with C.  Could someone help me with this simple
pointer passing problem.  I wanted to pass a ptr to a function and
have the function allocate some space and pass back the address in the ptr.
Here's what I tried:

#include <stdio.h>
main()
{
  extern void zip();
  int *ip;

  zip(ip);

  printf("*ip is %d\n",*ip);
}

void zip (iptr)
int *iptr;
{
  int * jptr;
  jptr = (int *) malloc(sizeof (int) );
  *jptr = 12;
  iptr = jptr;
}

	I know I could have passed back the pointer in a return statement,
I wanted to get this done correctly for now.  In the main program,
ip is <nil> on return, instead of pointing to jptr as I had hoped.

	Can someone explain what I should have done to get the desired
effect?  Thanks in advance for replies and suggestions.

regards,

	ric steinberger
	ric@ace.sri.com

willcr@bud.sos.ivy.isc.com (Will Crowder) (05/14/91)

In article <24268@unix.SRI.COM>, ric@ace.sri.com (Richard Steinberger) writes:
|> 
|> 	I am a bit rusty with C.  Could someone help me with this simple
|> pointer passing problem.  I wanted to pass a ptr to a function and
|> have the function allocate some space and pass back the address in the ptr.
|> Here's what I tried:

In the words of Agent 86, "Missed it by *that* much!"

|> #include <stdio.h>
|> main()
|> {
|>   extern void zip();
|>   int *ip;
|> 
|>   zip(ip);
should be
     zip(&ip);
|>   printf("*ip is %d\n",*ip);
|> }
|> 
|> void zip (iptr)
|> int *iptr;
should be
   int **iptr;
|> {
|>   int * jptr;
|>   jptr = (int *) malloc(sizeof (int) );
|>   *jptr = 12;
|>   iptr = jptr;
should be
     *iptr = jptr;
|> }

You need to pass the address of the object you want to modify to zip().
Since you're passing the address of an int pointer, the function zip()
should expect a "pointer to a pointer to an int".  Remember, in C, *everything*
is passed by value, even pointers.  Your code as it stood assumed that iptr
was being passed by reference.  So you missed it by three measly characters.
Other than that, the code is basically correct.

Will

--------------------------------------------------------------------------------
Will Crowder, MTS            | "I was gratified to be able to answer quickly,
(willcr@ivy.isc.com)         |  and I did: I said I didn't know."
INTERACTIVE Systems Corp.    |		-- Mark Twain

morrison@uhhacb.tmc.edu (Jay Morrison) (05/15/91)

In article <24268@unix.SRI.COM> ric@ace.sri.com (Richard Steinberger) writes:
>
>	I am a bit rusty with C.  Could someone help me with this simple
>pointer passing problem.  I wanted to pass a ptr to a function and
>have the function allocate some space and pass back the address in the ptr.
>Here's what I tried:
>  [etc...]
>


You have to pass a pointer to a pointer in this situation.  I had the
same problem in a lab for an operating systems class.  Programming queue
operations in C you need pointers to pointers also.

Try this:


#include <stdio.h>
main()
{
  extern void zip();
  int *ip;

  zip(&ip);

  printf("**ip is %d\n",*ip);
}

void zip (iptr)
int **iptr;
{
  int * jptr;
  jptr = (int *) malloc(sizeof (int) );
  *jptr = 12;
  *iptr = jptr;
}


The problem is that in C you always pass by reference, even when you
pass a pointer.  In other words, it is going pass a copy of the pointer,
and you are changing that copy.  Upon return to your main function, the
value it had there is restored.  So you need to pass a pointer to the
pointer, so that when you change the pointer (via *iptr = jptr), the
value will be there upon return to main.  Totally confused?  Think
about it for a while, its totally logical actually.

Another common problem you may encounter is a returning a FILE*
structure from a routine which opens a file.  In this situation you must
also use pointers to pointers.  This even had my professor confused as
to what was happening!! (temporarily).



----------------------------------------------------------------------
/   Jay Morrison                    \ "C programming:  all the power 
\   morrison@uhhacb.uhh.hawaii.edu  /   of assembly language with the 
/===================================    ease of assembly language..." 
\  *********** and God said:  "Let there be SURF!!" ***************          
----------------------------------------------------------------------

morrison@uhhacb.tmc.edu (Jay Morrison) (05/15/91)

I wrote:

>The problem is that in C you always pass by reference, even when you

I meant passed by value...sorry.



----------------------------------------------------------------------
/   Jay Morrison                    \ "C programming:  all the power 
\   morrison@uhhacb.uhh.hawaii.edu  /   of assembly language with the 
/===================================    ease of assembly language..." 
\  *********** and God said:  "Let there be SURF!!" ***************          
----------------------------------------------------------------------

gwyn@smoke.brl.mil (Doug Gwyn) (05/16/91)

In article <13012@uhccux.uhcc.Hawaii.Edu> morrison@uhhacb.tmc.edu (Jay Morrison) writes:
>The problem is that in C you always pass by reference, ...

No, it's always pass by value, which agrees with the further description
you gave.

>Another common problem you may encounter is a returning a FILE*
>structure from a routine which opens a file.  In this situation you must
>also use pointers to pointers.  This even had my professor confused as
>to what was happening!! (temporarily).

The standard practice for such a function is to make the FILE* its
return value, e.g.
	extern FILE *my_open( const char *name );
with a null pointer being returned when the function fails.

xwang@gmuvax2.gmu.edu (Xiang-Min Wang) (05/23/91)

In article <24268@unix.SRI.COM> ric@ace.sri.com (Richard Steinberger) writes:
>
>	I am a bit rusty with C.  Could someone help me with this simple
>pointer passing problem.  I wanted to pass a ptr to a function and
>have the function allocate some space and pass back the address in the ptr.
>Here's what I tried:
>
>#include <stdio.h>
>main()
>{
>  extern void zip();
>  int *ip;
>
>  zip(ip);
>
>  printf("*ip is %d\n",*ip);
>}
>
>void zip (iptr)
>int *iptr;
>{
>  int * jptr;
>  jptr = (int *) malloc(sizeof (int) );
>  *jptr = 12;
>  iptr = jptr;
>}
>
>	I know I could have passed back the pointer in a return statement,
>I wanted to get this done correctly for now.  In the main program,
>ip is <nil> on return, instead of pointing to jptr as I had hoped.
>
>	Can someone explain what I should have done to get the desired
>effect?  Thanks in advance for replies and suggestions.
>
>regards,
>
>	ric steinberger
>	ric@ace.sri.com

Hi, ric steinberger. if you knew "all parameters passed by value" in c,then
you could easily figure out where your code went wrong. your problem is a
typical c programming problem. I would suggest you to pass the address of 'ip'
and the rest of your code should be changed accordingly.

good luck, ric.

xwang

xwang@gmuvax2.gmu.edu