John wrote:[color=blue]
> I'm trying (struggling) to use realloc to grow a list of strings. The
> number of strings is not known (this is a subset of an assignment to write a
> recursive ls program... my BS was in EE, so I'm trying to catch up!).
>
> I'm working on the following program to try to figure this out. Now, I'm at
> the point where I'm filling up plines with (I belive) a list of pointers,
> each of which is pointing to a string ("foo 1", "foo 2", and so forth). The
> hard-coded 10 in the for loop, btw, is only for this exploration of ideas...
> It will not be in the final code (indeed, none of the hard-code numbers will
> be).
>
> My two sticking points are:
> 1) I'm supposed to "free" stuff that I've malloc'd. If I do free(p),
> then the pointers that I've stuffed into plines no longer point to anything,
> and the printout loop at the end of main confirms that when free(p) is in
> place.
>[/color]
The simple solution would free the allocations when you are finished
with them. So, change the printf loop to:
for( i=0; i<10; i++ )
{
printf(">>> %s \n",plines[i]);
free(plines[i]);
}
[color=blue]
> 2) I'm malloc'ing the correct size of each string, but how can I
> dynamically grow plines as needed? The realloc man page tells me that I can
> only realloc a thing that got it's address from a prior malloc... but where
> can I malloc plines? It reeks of a chicken/egg situation at 12:30am.
>[/color]
Instead of using char *plines[30], which fixes the max number of
strings you can allocate to 30, use char **. You can make a struct
that has a char ** member that points to the array and have another
member that keeps the count of the number of elements(strings)
allocated. You can write functions that manipulate this struct;
functions such as AddString, PrintStr, FreeStr. See the example.[color=blue]
>[/color]
[color=blue]
> char *plines[30];
>
> int main(void){
> char buf[1024];
>
> int i;
>
> for( i=0; i<10; i++ ){
> char temp[1024];
> sprintf(temp,"foo %d",i);
>
> char *p = malloc( strlen(temp) + 1 );
> strcpy(p,temp);
> plines[i]=p;
> }
>
> for( i=0; i<10; i++ )
> printf(">>> %s \n",plines[i]);
>[/color]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct sarray
{
char **line;
unsigned count;
};
int AddString(struct sarray *p, const char *s);
void FreeString(struct sarray *p);
void PrintString(struct sarray *p);
int main(void)
{
char buf[1024];
struct sarray mytest = {NULL}; /* Empty array */
int i;
for( i=0; i<10; i++ )
{
sprintf(buf,"foo %d",i);
AddString(&mytest, buf);
}
PrintString(&mytest);
FreeString(&mytest);
return 0;
}
int AddString(struct sarray *p, const char *s)
{
char **tmp;
if((tmp = realloc(p->line,
(p->count+1)*(sizeof *tmp))) == NULL)
return 0;
if(tmp)
{
p->line = tmp;
if((p->line[p->count] = malloc(strlen(s)+1)) == NULL)
return 0;
strcpy(p->line[p->count++],s);
}
return 1;
}
void FreeString(struct sarray *p)
{
unsigned i;
for(i = 0; i < p->count;i++)
free(p->line[i]);
free(p->line);
p->line = NULL;
p->count = 0;
return;
}
void PrintString(struct sarray *p)
{
unsigned i;
for(i = 0;i < p->count;i++)
printf("%6u: %s\n",i+1,p->line[i]);
return;
}
--
Al Bowers
Tampa, Fl USA
mailto:
xabowers@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/