Pointer to Array of Pointers to Strings. 
Author Message
 Pointer to Array of Pointers to Strings.

Hi,

I'm trying to dynamically allocate a Pointer to an Array of pointers that
point to strings or array of chars. This is what I got below. It doesn't
seem very graceful. But like this it seems more efficient with space
instead of making a array of say 5000 pointers (that would limit the
Dijkstra part of my program to a fixed number of nodes. Though in reality
it'd probably never get to 5000).

I was wondering if there was a "better" way as it looks sort of a novice
way to implement it.

Thanks for your time,

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

#define MAX_NAME_LENGTH 40

struct holder{
        char **list;

Quote:
};

struct holder *names;

/*
 * main: Test implementation of dynamically allocated
 *      array of pointers to strings.
 */
int main(void){
        int size=10;    /* Will read in. */
        char temp[]="Somebody";       /* Will read in. */

        /* Initialize. */
        names = malloc(sizeof(struct holder));
        assert(names != NULL);  /* Crash if out of memory. */
        names->list = malloc(size * sizeof(char*));
        assert(names->list != NULL);  /* Crash if out of memory. */

        names->list[0] = malloc(strlen(temp) + 1);
        strcpy(names->list[0], temp);

        printf("%s\n", names->list[0]);

        /* Clean up. */
        free(names->list[0]);
        free(names->list);
        free(names);

    return 0;

Quote:
}

--
SharkBoy


Fri, 16 Sep 2005 00:39:07 GMT  
 Pointer to Array of Pointers to Strings.
I was thinking that perhaps I could get rid of the struct that held the
array of pointers and just do something like below. But I get a
segmentation fault when trying to run the code below. I guess I need more
practice with pointers.

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

#define MAX_NAME_LENGTH 40

char **names;

/*
 * main: Test implementation of dynamically allocated
 *      array of pointers to strings.
 */
int main(void){
        int size = 15;

        *names = malloc(size * sizeof(char*));
        names[0] = malloc(size);

        free(*names);
        free(names[0]);

    return 0;

Quote:
}

--
SharkBoy


Fri, 16 Sep 2005 00:45:19 GMT  
 Pointer to Array of Pointers to Strings.

Quote:

> I was thinking that perhaps I could get rid of the struct that held the
> array of pointers and just do something like below.

I agree.

Quote:

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

> #define MAX_NAME_LENGTH 40

> char **names;

> /*
>  * main: Test implementation of dynamically allocated
>  * array of pointers to strings.
>  */
> int main(void){
>    int size = 15;

>    *names = malloc(size * sizeof(char*));

You haven't initialized names to point to valid storage. Replace
the line above with these lines (or similar). Note the argument to sizof

Something like
names = malloc(sizeof *names);
/*ALWAYS check for error*/
if(names == NULL)
{
    return EXIT_FAILURE;

Quote:
}

*names = malloc(size * sizeof **names);
if(*names == NULL)
{
    free(names);
    return EXIT_FAILURE;

Quote:
}
>    names[0] = malloc(size);

names[0] and *names is the same thing.
Note that names[N] is equivalent to *(names + N). In this case
N is 0 so names[0] is just the same as *names.

Quote:
>    free(*names);
>    free(names[0]);

Here you are freeing the same pointer twice. Not a very good
thing to do.

Looks like you are getting there at least :)

HTH, HAND.

--
Thomas.



Fri, 16 Sep 2005 01:10:10 GMT  
 Pointer to Array of Pointers to Strings.

Quote:


>> I was thinking that perhaps I could get rid of the struct that held the
>> array of pointers and just do something like below.

> I agree.

<lots of snipping>

Quote:

> Looks like you are getting there at least :)

> HTH, HAND.

I think I've got it. Thanks for your help!
(Error checking omitted for brevity)

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

char **names;

/*
 * main: Test implementation of dynamically allocated
 *      array of pointers to strings.
 */
int main(void){
        int numberOfNames = 15;
        int i;
        char thank[] = "Thank";
        char you[] = "you!";

        names = malloc(numberOfNames * sizeof(*names));

        names[0] = malloc(strlen(thank) + 1);
        names[1] = malloc(strlen(you) + 1);

        strcpy(names[0], thank);
        strcpy(names[1], you);

        for(i=0; i<2; i++){
                printf("%s ", names[i]);
        }
        printf("\n");

        free(names[0]);
        free(names[1]);
        free(names);

    return 0;

Quote:
}

(Time to reboot, all my memory leaks from before.)

--
SharkBoy



Fri, 16 Sep 2005 02:24:35 GMT  
 Pointer to Array of Pointers to Strings.

Quote:

> Hi,

> I'm trying to dynamically allocate a Pointer to an Array of pointers that
> point to strings or array of chars. This is what I got below. It doesn't
> seem very graceful. But like this it seems more efficient with space
> instead of making a array of say 5000 pointers (that would limit the
> Dijkstra part of my program to a fixed number of nodes. Though in reality
> it'd probably never get to 5000).

> I was wondering if there was a "better" way as it looks sort of a novice
> way to implement it.

> Thanks for your time,

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

> #define MAX_NAME_LENGTH 40

> struct holder{
>    char **list;
> };

> struct holder *names;

> /*
>  * main: Test implementation of dynamically allocated
>  * array of pointers to strings.
>  */
> int main(void){
>    int size=10;    /* Will read in. */
>    char temp[]="Somebody";       /* Will read in. */

>    /* Initialize. */
>    names = malloc(sizeof(struct holder));
>    assert(names != NULL);  /* Crash if out of memory. */
>    names->list = malloc(size * sizeof(char*));
>    assert(names->list != NULL);  /* Crash if out of memory. */

>    names->list[0] = malloc(strlen(temp) + 1);
>    strcpy(names->list[0], temp);

>    printf("%s\n", names->list[0]);

>    /* Clean up. */
>    free(names->list[0]);
>    free(names->list);
>    free(names);

>     return 0;
> }

IMO this code is not bad. I like the idea of putting the string
array inside a struct. I would put additional member in the
struct to represent the number of strings in the array. Then you
can write functions to add to the array, delete, modify and free
the allocations. Here is an example.

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

typedef struct NAME{
    char **name;
    size_t count;

Quote:
}NAME;

char *addNAME(NAME *p,const char *name);
void freeNAME(NAME *p);

int main(void)
{
    NAME president = {0}; /* initalized zero neccessary for start*/
    size_t i;

    addNAME(&president,"George Washington");
    addNAME(&president,"Abe Lincoln");
    puts("Presidents in the array are");
    for(i = 0; i < president.count;i++)
       printf("\t%s\n",president.name[i]);
    freeNAME(&president);
    printf("\nAfter freeing the array\n"
           "There are %u names in the array\n",president.count);
    return 0;

Quote:
}

char *addNAME(NAME *p, const char *name)
{
    char **tmp;
    size_t i;

    if(!p || !name) return NULL;
    i = p->count;
    if((tmp = realloc(p->name,(i+1)*sizeof(*p->name))) == NULL)
       return NULL;
    if((tmp[i] = malloc(strlen(name)+1)) == NULL)
       return NULL;
    strcpy(tmp[i],name);
    p->count++;
    p->name = tmp;
    return p->name[i];

Quote:
}

void freeNAME(NAME *p)
{
    size_t i;

    if(!p) return;
    for(i = 0;i < p->count;i++)
    free(p->name[i]);
    free(p->name);
    p->name = NULL;
    p->count = 0;

Quote:
}

---------
Al Bowers
Tampa, FL. USA

http://www.geocities.com/abowers822
comp.lang.c


Fri, 16 Sep 2005 02:27:18 GMT  
 Pointer to Array of Pointers to Strings.


Quote:

>IMO this code is not bad. I like the idea of putting the string
>array inside a struct. I would put additional member in the
>struct to represent the number of strings in the array. Then you
>can write functions to add to the array, delete, modify and free
>the allocations. Here is an example.

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

>typedef struct NAME{
>    char **name;
>    size_t count;
>}NAME;

>char *addNAME(NAME *p,const char *name);
>void freeNAME(NAME *p);

>int main(void)
>{

/*printf("blah...");*/

Quote:
>    NAME president = {0}; /* initalized zero neccessary for start*/

I got a warning: missing initializer with gcc -Wall -W -pedantic.
Could you explain the {}'s usage for structure init?

BTW, when I add printf("blah ...");
before the president definition, gcc -Wall -W -pedantic issues another
warning: parse error before 'president', 'president' undeclared.
What does it imply?

Another BTW, what '-W' is used for? I saw that somewhere but not
obviously on the gcc -v --help output.

And... you see I am refreshing my limited C knowledges.. is president
above being static defaultly?

Thanks for your help,
Wenjie



Sat, 17 Sep 2005 16:19:43 GMT  
 Pointer to Array of Pointers to Strings.

ons. Here is an example.

Quote:

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

>>typedef struct NAME{
>>   char **name;
>>   size_t count;
>>}NAME;

>>char *addNAME(NAME *p,const char *name);
>>void freeNAME(NAME *p);

>>int main(void)
>>{

> /*printf("blah...");*/

>>   NAME president = {0}; /* initalized zero neccessary for start*/

> I got a warning: missing initializer with gcc -Wall -W -pedantic.
> Could you explain the {}'s usage for structure init?

You have turned on, probably with the -W argument, a high
level of warning, that identifies areas of code that generally
may not be questionable but which you want to be made aware of.

In this case with declaration of the struct:
NAME president = {0};
The bracket is only explicitly initializing the first struct member.
You are being warned that the next member, president.count, was
not explicitly initialized. However, the C Standard guarantees
that the member president.count will be inplicitly initialized with
0. This is what you want, president.name to have the value
NULL,ie. 0, and president.count to have the value of 0.

You would probably be able to silence the warning if you fully
initialized, explicitly, the members with
NAME president = {NULL,0};

The struct members are initialized the same, whether the bracket is
{0} or {NULL,0}.

Quote:

> BTW, when I add printf("blah ...");
> before the president definition, gcc -Wall -W -pedantic issues another
> warning: parse error before 'president', 'president' undeclared.
> What does it imply?

The struct object, president, is being declared in the function main.
You can't use  the object before the object is declared.

---
Al Bowers
Tampa, FL. USA

http://www.geocities.com/abowers822
comp.lang.c



Sat, 17 Sep 2005 21:22:12 GMT  
 Pointer to Array of Pointers to Strings.

Quote:


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

>>typedef struct NAME{
>>    char **name;
>>    size_t count;
>>}NAME;

>>char *addNAME(NAME *p,const char *name);
>>void freeNAME(NAME *p);

>>int main(void)
>>{
>/*printf("blah...");*/
>>    NAME president = {0}; /* initalized zero neccessary for start*/

>I got a warning: missing initializer with gcc -Wall -W -pedantic.

An excellent reason for NOT using -W.  The guys who decided that -Wall
should not include the -W warnings knew what they were doing; no need to
try to outsmart them.

Quote:
>Could you explain the {}'s usage for structure init?

This is how structures are initialised with constant data.  See your C
book for further details.

Quote:
>BTW, when I add printf("blah ...");
>before the president definition, gcc -Wall -W -pedantic issues another
>warning: parse error before 'president', 'president' undeclared.
>What does it imply?

Isn't it OBVIOUS?!?  Unless you're using a conforming C99 compiler, you
can't have declarations *after* statements, at the same block level.

Quote:
>Another BTW, what '-W' is used for?

To shoot yourself in the foot with (mostly) unneeded warnings.

Quote:
>And... you see I am refreshing my limited C knowledges..

Which is best achieved by perusing a good C book.

Quote:
>is president above being static defaultly?

Nope: inside a function, the default is automatic.  That's why you're
not likely to ever see the keyword "auto" actually used in a C program.

Dan
--
Dan Pop
DESY Zeuthen, RZ group



Sat, 17 Sep 2005 21:46:42 GMT  
 Pointer to Array of Pointers to Strings.


Quote:
>In this case with declaration of the struct:
>NAME president = {0};
>The bracket is only explicitly initializing the first struct member.
>You are being warned that the next member, president.count, was
>not explicitly initialized. However, the C Standard guarantees
>that the member president.count will be inplicitly initialized with
>0. This is what you want, president.name to have the value
>NULL,ie. 0, and president.count to have the value of 0.

I checked a perhaps outdated C FAQ 1.30 and saw no anwser to why
president.count is implicitly init as 0. Probably structure and
array has different init rules? I remember in:
int main(void) {
    char name[10] = "not president";
    /* ... */
Quote:
}

name is taken regarded as a static array? Then I guess it is similar
for a struct definition (concerning initialization) Sorry I don't have
a standard at hand.

Quote:

>The struct object, president, is being declared in the function main.
>You can't use  the object before the object is declared.

FYI, I didn't mean to print out president before declaring it. But
Dan seems to have anwered my question. So how could I know gcc is
using C90 or C99?

Quote:
>---
>Al Bowers
>Tampa, FL. USA

>http://www.geocities.com/abowers822
>comp.lang.c

Thanks and best regards,
(I mis-sent the email just now ...)
Wenjie


Sun, 18 Sep 2005 10:54:57 GMT  
 Pointer to Array of Pointers to Strings.

Quote:



>>In this case with declaration of the struct:
>>NAME president = {0};
>>The bracket is only explicitly initializing the first struct member.
>>You are being warned that the next member, president.count, was
>>not explicitly initialized. However, the C Standard guarantees
>>that the member president.count will be inplicitly initialized with
>>0. This is what you want, president.name to have the value
>>NULL,ie. 0, and president.count to have the value of 0.

> I checked a perhaps outdated C FAQ 1.30 and saw no anwser to why
> president.count is implicitly init as 0. Probably structure and
> array has different init rules? I remember in:

You need to study the C Standard, which defines the language.

 From the standard
6.7.8.19 Initialization
"all subobjects that are not initialized explicitly shall be
initialized implicitly the same as objects that have static
duration."

This refers to 6.7.8.10
"If an object that has static duration is not initialized explicitly
then
....
-- if it is arithmetic type, it is initialized to (positive or negative)
zero."

Therefore, president.count, an arithmetic type, is initialized zero.

-------------
Al Bowers
Tampa, FL. USA

http://www.geocities.com/abowers822
comp.lang.c



Sun, 18 Sep 2005 12:26:38 GMT  
 Pointer to Array of Pointers to Strings.

Quote:

> FYI, I didn't mean to print out president before declaring it. But
> Dan seems to have anwered my question. So how could I know gcc is
> using C90 or C99?

You should check the documentation.  As predicted by another poster,
off-topic gcc questions usually get answered, anyway.  Use the
appropriate flags:
(the default, no flags) is equivalent to -std=gnu89, ISO 89 (90) + gnu
extensions
C89 (or C90) without gnu extensions is -std=c89, -std=iso9899:1990, or -ansi
The current approximation to C99 is -std=c99, -std=c9x,
-std=iso9899:1999, or -std=iso9899:199x.  The versions with 'x' rather
than '9' are depricated.
The current approximation to C99 + gnu extensions is -std=g99 or the
deprecated -std=g9x


Sun, 18 Sep 2005 12:54:24 GMT  
 
 [ 11 post ] 

 Relevant Pages 

1. Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers

2. Copy Array string to another Pointer array string in ANSI-C

3. Pointer of Pointers was Pointer of arrays...

4. Pointers: return of pointer to array of pointers to main

5. Array of pointers, pointer to array...

6. array pointer/pointer array

7. arrays pointers array of pointers

8. convert list to array, arrays of pointers (to strings)

9. Pointer to array of pointers

10. pointers to pointers to arrays

11. Pointer to an array of pointers to functions

12. limit on pointer to array of pointers?

 

 
Powered by phpBB® Forum Software