Re: Returning an array of strings in C



DanielJohnson said:

<snip>

If I understand it correctly, allocate memeory using malloc in the
fucntion and return char** type. Please correct me if I am wrong.

Okay, let's not worry about the data source for now, and just focus on
the return technique.

First, the bad news: you can't return an array from a C function.

Now, the good news: you can fake it.

Let's start off with a generic demonstration, using a type T (just some
type or other):

#include <stdlib.h>
#include <stdio.h>

#include "t.h" /* no, this doesn't exist - we're faking it for now */

T *t_create(size_t n, FILE *in)
{
T *new = malloc(n * sizeof *new); /* space for n objects of type T */
if(new != NULL)
{
size_t i = 0;
while(i < n)
{
/* give new[i] a value in some program-specific manner */
t_populate_from_file(&new[i++], in);
}
}
return new;
}

First, we create the storage space. Then we check that it worked. Then
we populate the array. Then we return a pointer to its first element.
DO NOT modify 'new' in any way in this function - its value is
important, as it marks the start of the memory space allocated to you.

You'd collect the array something like this:

T *lots_of_t = t_create(42, stdin);
if(lots_of_t != NULL)
{
use the array here, and when you've eventually finished, you:

free(lots_of_t); /* CAUTION! See below. */


If T is a simple type, e.g. an int or a double or a struct full of only
simple types, then you can free it as shown.

That's the general method. Now for strings it gets a bit more
complicated, because we need to allocate space for the strings
themselves.

Let's start off with a simple routine for creating a fresh copy of a
string by allocating storage:

#include <string.h>
#include <stdlib.h>

char *dupstr(const char *s)
{
size_t len = strlen(s) + 1;
char *new = malloc(len * sizeof *new);
if(new != NULL)
{
memcpy(new, s, len);
}
return new;
}

Strings thus created can be released by free().

Now we are in a position to write our array allocator. I've pinched
t_create and hacked it, replacing T with char * (which means that T *
is replaced with char * *, of course):

char * * str_create(size_t n)
{
char * *new = malloc(n * sizeof *new);
if(new != NULL)
{
size_t i = 0;
while(i < n)
{
new[i++] = dupstr("Mary had a little lamb");
}
}
return new;
}

This'll give you n copies of "Mary had a little lamb", of course. You
can hack the loop to your tastes. Bear in mind that any or all of new's
members may have the value NULL instead of a pointer to a block of
memory containing "Mary had a little lamb", but that's the risk you
take when allocating memory dynamically. Be Prepared.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
.



Relevant Pages

  • Re: files and directories into an array of arrays
    ... can use an array of arrays of char: ... out that you in fact need 43 strings, ... struct filename * next; ... size array in struct filename is wasteful and that you can easily replace it ...
    (comp.lang.c)
  • Re: two dimensional arrays passed to functions
    ... > array and then send it down as a single dimmensional array. ... x is an array of char pointers. ... to a pointer to the first element of this array, ... need to copy the strings and not just assign pointers to them). ...
    (comp.lang.c)
  • Re: a string, a string array and character array
    ... which defined its "char" to be in the range -128 to 127. ... with strings, like sorting. ... A character array is an array of character type; ...
    (comp.soft-sys.matlab)
  • Re: Help - JNI and JMS - data conversion problems
    ... DataOutputStream in a raw byte array. ... Note when you do this your Strings will be counted UTF-8 format. ... You could write them an char[] if you wanted the simplicity of 16-bit ...
    (comp.lang.java.programmer)
  • Re: clarification on delete []
    ... > What does the size of char have to do with it? ... This is not similar, since you're allocating an array of pointers, ...
    (comp.lang.cpp)