[Q] Initialise a struct with variable length cahracter strings

Discussion in 'C Programming' started by Stuart Norris, Sep 25, 2003.

  1. Dear Readers,

    I am attempting to initialise a struct contiaing a dynamic character
    string. In the example below I am trying to initialise the name field
    so that my struct does not waste space. I know if I change char
    name[80] this will work, but I will waste alot of space. (I am
    learning so I want to learn the best way)

    How can I define a struct the allows variable length character strings
    in the
    definition?

    Thank

    Stuart

    #include <stdio>
    #include <stdlib>

    int main (int argc, char **argv)
    {
    struct command
    {
    unsigned int cmd;
    unsigned int olen;
    unsigned int ilen;
    char name[];
    } init[] = {{0,0,0,"Name A"},{0,0,0,"Name B 123"}};
    }
    Stuart Norris, Sep 25, 2003
    #1
    1. Advertising

  2. Stuart Norris

    Tom Zych Guest

    Stuart Norris wrote:

    > How can I define a struct the allows variable length character strings
    > in the
    > definition?


    > struct command
    > {
    > unsigned int cmd;
    > unsigned int olen;
    > unsigned int ilen;
    > char name[];

    char *name;
    > } init[] = {{0,0,0,"Name A"},{0,0,0,"Name B 123"}};


    --
    Tom Zych
    This is a fake email address to thwart spammers.
    Real address: echo '' | rot13
    Tom Zych, Sep 25, 2003
    #2
    1. Advertising

  3. Stuart Norris

    Mike Wahler Guest

    "Stuart Norris" <> wrote in message
    news:...
    > Dear Readers,
    >
    > I am attempting to initialise a struct contiaing a dynamic character
    > string. In the example below I am trying to initialise the name field
    > so that my struct does not waste space. I know if I change char
    > name[80] this will work, but I will waste alot of space. (I am
    > learning so I want to learn the best way)
    >
    > How can I define a struct the allows variable length character strings
    > in the
    > definition?
    >
    > Thank
    >
    > Stuart
    >
    > #include <stdio>
    > #include <stdlib>
    >
    > int main (int argc, char **argv)
    > {
    > struct command
    > {
    > unsigned int cmd;
    > unsigned int olen;
    > unsigned int ilen;
    > char name[];


    const char *name;

    > } init[] = {{0,0,0,"Name A"},{0,0,0,"Name B 123"}};
    > }


    Note that you must not modify what 'name' points to.

    -Mike
    Mike Wahler, Sep 25, 2003
    #3
  4. Stuart Norris

    Nick Austin Guest

    On 24 Sep 2003 17:53:35 -0700, (Stuart
    Norris) wrote:

    >Dear Readers,
    >
    >I am attempting to initialise a struct contiaing a dynamic character
    >string. In the example below I am trying to initialise the name field
    >so that my struct does not waste space. I know if I change char
    >name[80] this will work, but I will waste alot of space. (I am
    >learning so I want to learn the best way)
    >
    >How can I define a struct the allows variable length character strings
    >in the
    >definition?
    >
    >Thank
    >
    >Stuart
    >
    >#include <stdio>
    >#include <stdlib>


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

    >int main (int argc, char **argv)
    >{
    > struct command
    > {
    > unsigned int cmd;
    > unsigned int olen;
    > unsigned int ilen;
    > char name[];


    This is an incomplete type which means that the entire structure
    will also be an incomplete type.

    You cannot define an array of incomplete types. Change this
    to:
    char *name;
    or:
    char name[11];

    > } init[] = {{0,0,0,"Name A"},{0,0,0,"Name B 123"}};
    >}


    Nick.
    Nick Austin, Sep 25, 2003
    #4
  5. Stuart Norris

    Al Bowers Guest

    Stuart Norris wrote:
    > Dear Readers,
    >
    > I am attempting to initialise a struct contiaing a dynamic character
    > string. In the example below I am trying to initialise the name field
    > so that my struct does not waste space. I know if I change char
    > name[80] this will work, but I will waste alot of space. (I am
    > learning so I want to learn the best way)
    >
    > How can I define a struct the allows variable length character strings
    > in the
    > definition?
    >


    > struct command
    > {
    > unsigned int cmd;
    > unsigned int olen;
    > unsigned int ilen;
    > char name[];
    > } init[] = {{0,0,0,"Name A"},{0,0,0,"Name B 123"}};


    It it is unacceptable to declare fixed arrays then I would suggest
    that you dynamically allocated space. Write a function that will
    allocate and assign.

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

    struct command
    {
    unsigned int cmd;
    unsigned int olen;
    unsigned int ilen;
    char *name;
    };

    struct CommandArray
    {
    struct command *command;
    unsigned count;
    };

    struct command *AddStruct(struct CommandArray *p, unsigned cmd,
    unsigned olen, unsigned ilen, const char *name);
    void FreeStruct(struct CommandArray *p);

    int main(void)
    {
    struct CommandArray test = {NULL, 0};
    unsigned i;

    AddStruct(&test, 0,0,0, "Name A");
    AddStruct(&test, 0,0,0, "Name B 123");
    for(i = 0; i < test.count; i++)
    printf("test.command[%u].name = \"%s\"\n",
    i,test.command.name);
    FreeStruct(&test);
    return 0;
    }

    struct command *AddStruct(struct CommandArray *p, unsigned cmd,
    unsigned olen, unsigned ilen, const char *name)
    {
    struct command *temp;
    unsigned i = p->count;

    temp = realloc(p->command, (sizeof *p->command)*(i+1));
    if(temp == NULL) return NULL;
    p->command = temp;
    if((p->command.name = malloc(strlen(name)+1)) == NULL)
    return NULL;
    strcpy(p->command.name,name);
    p->command.ilen = ilen;
    p->command.olen = olen;
    p->command.cmd = cmd;
    p->count++;
    return &p->command;
    }

    void FreeStruct(struct CommandArray *p)
    {
    unsigned i;

    for(i = 0;i < p->count; i++)
    free(p->command.name);
    free(p->command);
    p->command = NULL;
    p->count = 0;
    }


    --
    Al Bowers
    Tampa, Fl USA
    mailto: (remove the x)
    http://www.geocities.com/abowers822/
    Al Bowers, Sep 25, 2003
    #5
  6. On Thu, 25 Sep 2003 04:39:42 +0100, Nick Austin
    <> wrote:

    > On 24 Sep 2003 17:53:35 -0700, (Stuart
    > Norris) wrote:

    <snip>
    > > struct command
    > > {
    > > unsigned int cmd;
    > > unsigned int olen;
    > > unsigned int ilen;
    > > char name[];

    >
    > This is an incomplete type which means that the entire structure
    > will also be an incomplete type.
    >

    In C90, that is a constraint violation; a struct (or union) member
    cannot have incomplete type at all. In C99, as the last member, that
    is a flexible array member, the blessed form of the struct hack. It
    does not make the containing struct incomplete; instead the struct
    type has only the size of the fixed header, and you the programmer are
    responsible for allocating/managing memory space for any objects that
    also contain the variable part.

    > You cannot define an array of incomplete types.


    True, but irrelevant in either case. You *can* have an array of
    FAMiful elements, but they do not allow any space for the variable
    parts, as is needed in this application.

    > Change this
    > to:
    > char *name;
    > or:
    > char name[11];
    >
    > > } init[] = {{0,0,0,"Name A"},{0,0,0,"Name B 123"}};
    > >}

    >

    Right. Of course the former wastes space, which is what the OP asked
    to avoid, although unless there are thousands of these or the maximum
    length is (and needs to be) much more than the 11 shown or this is a
    very constrained embedded system I wouldn't worry about it; and the
    latter wastes a pointer in each struct as well as making the targets
    not (safely) writable, if that matters.

    The FAMly alternative, which cannot be initialized in the language
    sense, but only set at runtime perhaps startup:
    struct command * array[WHATEVER];
    /* error checking omitted */
    array[0] = malloc(sizeof(struct command)+strlen(str1)+1);
    array[0]->cmd = 0; ... strcpy(array[0]->name, str1);
    array[1] = malloc(sizeof(struct command)+strlen(str2)+1);
    array[1]->cmd = 0; ... strcpy(array[1]->name, str2);
    etc.


    - David.Thompson1 at worldnet.att.net
    Dave Thompson, Sep 29, 2003
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nandan
    Replies:
    4
    Views:
    403
    Tor Iver Wilhelmsen
    Apr 29, 2005
  2. Simon Elliott
    Replies:
    2
    Views:
    28,568
    Simon Elliott
    Apr 13, 2005
  3. iceColdFire
    Replies:
    9
    Views:
    511
    John Carson
    May 23, 2005
  4. Girish Sahani
    Replies:
    17
    Views:
    571
    Boris Borcic
    Jun 9, 2006
  5. Replies:
    18
    Views:
    7,079
    Karl Heinz Buchegger
    Jul 22, 2005
Loading...

Share This Page