[comp.lang.c] Buffer referencing between functions.

robert@sri-spam.istc.sri.com (Robert Allen) (10/20/87)

    Pardon me if this question seems naive, but I've
    been thinking about it and need some authoritative
    answers.

    Below is a code fragment to illustrate my problem;

    struct stack_vars {
	char *frombuf;
	int frombuf_index;	/* 0-2000 */

	char *tobuf;
	int frombuf_index;	/* 0-2000 */
    }

    void
    calling(inbuf,inbuf_index)
    char inbuf[];
    int inbuf_index;
    {
	struct stack_vars data;
	char dbuf[2000];

	data.frombuf = inbuf;
	data.frombuf_index = inbuf_index;

	data.tobuf = dbuf;
	data.tobuf_index = 0;

	called(&data);
    }

    void
    called(sv)
    struct stack_vars *sv;
    {
	/* do some buffer processing */
	bcopy(sv->frombuf,sv->tobuf,sv->frombuf_index);
	sv->tobuf_index = sv->frombuf_index;
    }


    In the example above "called()" depends on the fact that the
    pointer passed to the automatic variable 'dbuf' in "calling()"
    is correct.
    
    Based on my experience the above code fragement should work,
    since the stuff is passed on the stack and the calling routine
    is not "temporarily deallocated".  My question is, is it
    technically correct to reference an 'external' variable via a
    pointer in this manner?  If the allocated space in dbuf were
    global to the file or the program I wouldn't be suspicious, but
    since it is an automatic variable in a calling function I'm a bit
    concerned with the correctness of it.

    Email or posting of information will be greatly appreciated.

-- 
---------------------------------------------------------

Robert Allen,
robert@spam.istc.sri.com
415-859-2143 (work phone, days)

---------------------------------------------------------

barmar@think.COM (Barry Margolin) (10/21/87)

In article <10756@sri-spam.istc.sri.com> robert@sri-spam.istc.sri.com (Robert Allen) writes:
[example deleted]
>    In the example above "called()" depends on the fact that the
>    pointer passed to the automatic variable 'dbuf' in "calling()"
>    is correct.
>    
>    ... My question is, is it
>    technically correct to reference an 'external' variable via a
>    pointer in this manner?

Yes, it is fine.  A pointer to an automatic variable is valid until
the function in which the automatic variable was declared returns.
So, it is OK to pass such pointers to called routines.  What WOULDN'T
be valid would be for calling() to end with

	return &dbuf;

(assuming calling() were declared to return char* rather than void, of
course).  This would return a pointer to deallocated storage, which
would be useless (and potentially hazardous) to the caller.  In
between is the case of storing such a pointer in another non-automatic
structure; you must make sure that this field is never dereferenced
between the time calling() returns and the time it is given a new
value.


---
Barry Margolin
Thinking Machines Corp.

barmar@think.com
seismo!think!barmar

dg@wrs.UUCP (David Goodenough) (10/27/87)

In article <10756@sri-spam.istc.sri.com> robert@sri-spam.istc.sri.com (Robert Allen) writes:
>    Below is a code fragment to illustrate my problem;
>
>    struct stack_vars {
>	char *frombuf;
>	int frombuf_index;	/* 0-2000 */
>	char *tobuf;
>	int tobuf_index;	/* 0-2000 */
>    };
>
>    void calling(inbuf,inbuf_index)
>    char inbuf[];
>    int inbuf_index;
>    {
>	struct stack_vars data;
>	char dbuf[2000];
>
>	data.frombuf = inbuf;
>	data.frombuf_index = inbuf_index;
>	data.tobuf = dbuf;
>	data.tobuf_index = 0;
>	called(&data);
>    }
>
>    void called(sv)
>    struct stack_vars *sv;
>    {
>	bcopy(sv->frombuf,sv->tobuf,sv->frombuf_index);
>	sv->tobuf_index = sv->frombuf_index;
>    }

Referencing dbuf via the pointer data.tobuf in the above section is legal,
fair game, and I do similar sorts of things all the time. The main danger
when passing pointers to locals around on the stack is NOT TO DO THIS:

	char *stug()
	 {
	    char blurf[100];

	    /* do something interesting */

	    return(blurf);
	 }

I.E. Don't return a pointer to a local variable, because by the time you use
it it is no longer valid, at best it will still be there, at worst another
procedure call will have overwritten it.
--
		dg@wrs.UUCP - David Goodenough

		..... !rtech!--\
				>--!wrs!dg
		  ..... !sun!--/

					+---+
					| +-+-+
					+-+-+ |
					  +---+