[comp.lang.c] pointer->pointer problem

reilly@bnlux1.bnl.gov (kevin reilly) (04/04/91)

I have the following problem with a piece of code.
If someone could please tell me what I am doing wrong I woulde be quite
grateful!

FUNC1 returns the address of an array of pointers to strings.
FUNC2 does some string manipulations.

main()
{
char **outPt;

outPut = FUNC1(...);
FUNC2(outPut);
}

char **FUNC1(...)
{
static char *lines[10];
/* do stuff */
return &lines[0];
}

void FUNC2(char **inPut)
{
/* If I manipulate the strings pointed to by inPut in this function
	it seems other strings are also effected.
   Why is this?
*/

}

reilly@bnlux1.bnl.gov

richter@immd4.informatik.uni-erlangen.de (Joachim Richter) (04/05/91)

In article <1991Apr3.174058.13536@bnlux1.bnl.gov> reilly@bnlux1.bnl.gov (kevin reilly) writes:
>I have the following problem with a piece of code.
>If someone could please tell me what I am doing wrong I woulde be quite
>grateful!
>
>FUNC1 returns the address of an array of pointers to strings.
>FUNC2 does some string manipulations.
>
>main()
>{
>char **outPt;
>
>outPut = FUNC1(...);
>FUNC2(outPut);
>}
>
>char **FUNC1(...)
>{
>static char *lines[10];
>/* do stuff */
>return &lines[0];
>}
>
>void FUNC2(char **inPut)
>{
>/* If I manipulate the strings pointed to by inPut in this function
>	it seems other strings are also effected.
>   Why is this?
>*/
>}

Which *other* strings ? This is C, not ModulaOrAnotherWirthLessThing.
	Ingo

rjohnson@shell.com (Roy Johnson) (04/05/91)

In article <1991Apr3.174058.13536@bnlux1.bnl.gov> reilly@bnlux1.bnl.gov (kevin reilly) writes:
>FUNC1 returns the address of an array of pointers to strings.
>FUNC2 does some string manipulations.

>main()
>{
>char **outPt;

>outPut = FUNC1(...);
>FUNC2(outPut);
>}

>char **FUNC1(...)
>{
>static char *lines[10];
>/* do stuff */
>return &lines[0];
>}

>void FUNC2(char **inPut)
>{
>/* If I manipulate the strings pointed to by inPut in this function
	   it seems other strings are also effected.
>   Why is this?
>*/
>}

This sort of problem sure strikes a lot of people.

Nit-pick: You could have FUNC1 return lines, rather than &lines[0]

The real problem is that lines is array of pointers to char, but
you do not (apparently) allocate memory for those pointers to point
to, so you're slogging around in uncharted waters.

Try

char **FUNC1(...)
{
static char lines[10][MAX_STRLEN];
/* do stuff */
return lines;
}

or

in /* do stuff */, you could have

int i;
for (i = 0; i < 10; ++i)
  lines[i]=(char *)malloc(some_length);

where some_length is calculated on the fly.  If you are allocating
space for lines, then I have no answer for why you're getting the
behavior you are.

Hope this helps.
--
======= !{sun,psuvax1,bcm,rice,decwrl,cs.utexas.edu}!shell!rjohnson =======
Feel free to correct me, but don't preface your correction with "BZZT!"
Roy Johnson, Shell Development Company

rjohnson@shell.com (Roy Johnson) (04/05/91)

In article <1991Apr3.174058.13536@bnlux1.bnl.gov> reilly@bnlux1.bnl.gov (kevin reilly) writes:

>char **FUNC1(...)
>{
>static char *lines[10];
>/* do stuff */
>return &lines[0];
>}

I just realized that lines is static, so it *should* all be initialized
to zero (NULL) pointers; give us more information on what you are doing
with lines.  If you are assigning it like

lines[4]=another_string;

then any changes you make to lines[4] will of course change
another_string, and what you would probably want to do is allocate
space for lines[4] (as in my last response) and
 strcpy(lines[4], another_string);

--
======= !{sun,psuvax1,bcm,rice,decwrl,cs.utexas.edu}!shell!rjohnson =======
Feel free to correct me, but don't preface your correction with "BZZT!"
Roy Johnson, Shell Development Company

mostek@motcid.UUCP (Frank B. Mostek) (04/06/91)

reilly@bnlux1.bnl.gov (kevin reilly) writes:

>main()
>{
>char **outPt;

>outPut = FUNC1(...);
>FUNC2(outPut);
>}

>char **FUNC1(...)
>{
>static char *lines[10];
        ^^^^^^^^^^^^^^^
You have commited the dreaded C string memory allocation error.
Your problem is analogous to the following:

char *p;

strcpy(p, "BLOW AWAY SOME MEMORY, HOPEFULLY YOUR OS HAS MEM PROTECTION");

You need to allocate space for each pointer.

E.g.  line[1] = malloc(strlen(str) + 1);	/* Normally called strsave() */
      strcpy(line[1], str);

OR, you could declare a 2 dimensional array. (if you know in advance how big
everything is going to be.)

Hope this helps.
-- 
************************************************************
Frank Mostek			uunet!motcid!amethyst!mostek
Software Consultant 		(708)632-7191
************************************************************

throopw@sheol.UUCP (Wayne Throop) (04/08/91)

> reilly@bnlux1.bnl.gov (kevin reilly)
> [...whitespace squeezed for brevity...]
> main() { char **outPt; outPut = FUNC1(...); FUNC2(outPut); }
> char **FUNC1(...) { static char *lines[10]; /* do stuff */ return
>     &lines[0]; }
> void FUNC2(char **inPut) { /* If I manipulate the strings pointed to by
>     inPut in this function it seems other strings are also effected.  
>     Why is this? */ }

*What* strings pointed to by inPut?  These pointers have never been
initialized to point to anything.  (In fact, being static, they've
been initialized to point to *no*thing, and since nil pointers
often in "reality" point to the same non-place, this is likely
the cause of the aliasing observed.)

And while we're at it, isn't terribly wise to redeclare function
return types (from (int) to (char**) and from (int) to (void)).
It is likewise unwise to fail to return a value from "main".
--
Wayne Throop  ...!mcnc!dg-rtp!sheol!throopw