dynamic declaration of struct array

Discussion in 'C Programming' started by Tim, Oct 10, 2003.

  1. Tim

    Tim Guest

    Why won't the declaration of a struct array work if I do it like this:

    1 typedef struct
    2 {
    3 int pens;
    4 int pencils;
    5 } Stationers;
    6

    .........

    7 int main(void)
    8 {
    9 int num;

    ...........num defined in code........

    10
    11 Stationers stats[num];
    12 }

    The error message says "constant expression required" and highlights
    line 11. I want to declare it dynamically during runtime, could
    someone explain how to do this please.
    Tim, Oct 10, 2003
    #1
    1. Advertising

  2. Tim

    Noah Roberts Guest

    Tim wrote:
    Stationers stats[num];
    > 12 }
    >
    > The error message says "constant expression required" and highlights
    > line 11. I want to declare it dynamically during runtime, could
    > someone explain how to do this please.


    Stationers *stats = (Stationers*)malloc(num * sizeof(Stationers));

    NR
    Noah Roberts, Oct 10, 2003
    #2
    1. Advertising

  3. "Tim" <> wrote in message
    news:...
    > Why won't the declaration of a struct array work if I do it like this:

    ....
    > 7 int main(void)
    > 8 {
    > 9 int num;
    >
    > ...........num defined in code........
    >
    > 10
    > 11 Stationers stats[num];
    > 12 }
    >
    > The error message says "constant expression required" and highlights
    > line 11. I want to declare it dynamically during runtime, could
    > someone explain how to do this please.


    This code is actually valid if your compiler implements the 1999
    C standard. Prior to that, array variables are indeed required
    to be of a size known at compile time.

    The backwards-compatible way to do what you want is to use:
    Stationers* stats = (Stationers*)malloc(num*sizeof(Stationers));
    ... use stats as if it were an array of size num ...
    free(stats); // don't forget this prior to exit !


    Hope this helps,
    Ivan
    --
    http://ivan.vecerina.com
    Ivan Vecerina, Oct 10, 2003
    #3
  4. In article <>,
    Tim <> wrote:
    >Why won't the declaration of a struct array work if I do it like this:


    [snip struct definition]

    >7 int main(void)
    >8 {
    >9 int num;
    >
    > ...........num defined in code........
    >
    >10
    >11 Stationers stats[num];
    >12 }
    >
    >The error message says "constant expression required" and highlights
    >line 11. I want to declare it dynamically during runtime, could
    >someone explain how to do this please.


    Uhmm... what language are you trying to write this code in?

    If you're using C99, what you have here should work, since arrays are
    allowed to have lengths that aren't known until run-time.

    If you're using C90, you're not allowed to declare a new variable (like
    the array) after non-declaration stuff (like assigning a value to num),
    so once you fill in the blanks your code will still be broken no matter
    how you declare the array. Instead, you'd need to declare a pointer at
    the beginning of the block and, once you've decided how many elements
    you want, use malloc to allocate memory for it:
    --------
    #include <stdlib.h>

    /*Define and typedef the Stationers struct here*/

    int main(void)
    {
    int num;
    Stationers *stats;

    /*Decide on a value for num here*/

    stats=malloc(num * sizeof *stats);

    /*I assume you'll want to do something with stats here*/

    free(stats);
    }
    --------

    If you're using C++ (which also allows declarations after non-
    declarations), go to comp.lang.c++ and ask about (or, better, open a
    textbook and read about) new[] and std::vector.


    dave

    --
    Dave Vandervies
    So "Patterns" are really just another name for "Object-oriented programming",
    which is really just another name for "Structured programming", which is really
    just big words for "good hacking". --Richard Bos in comp.lang.c
    Dave Vandervies, Oct 10, 2003
    #4
  5. (Tim) wrote:

    >Why won't the declaration of a struct array work if I do it like this:
    >
    >1 typedef struct
    >2 {
    >3 int pens;
    >4 int pencils;
    >5 } Stationers;
    >6
    >
    > .........
    >
    >7 int main(void)
    >8 {
    >9 int num;
    >
    > ...........num defined in code........
    >
    >10
    >11 Stationers stats[num];
    >12 }
    >
    >The error message says "constant expression required" and highlights
    >line 11. I want to declare it dynamically during runtime, could
    >someone explain how to do this please.


    Yes, you have to define a pointer and dynamically allocate memory for
    it to point to, look:

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

    typedef
    struct
    {
    int pens;
    int pencils;
    }
    Stationers;

    int main( void )
    {
    int num;
    Stationers *stats;

    /* calculate value for num, e.g: */
    num = 42;

    stats = malloc( num * sizeof *stats );
    if ( stats == NULL )
    {
    fprintf( stderr, "Memory allocation error." );
    return EXIT_FAILURE;
    }

    /* do something with stats, e.g: */
    stats[ 7 ].pens = 6;
    stats[ 7 ].pencils = 9;

    return EXIT_SUCCESS;
    }

    Regards
    --
    Irrwahn
    ()
    Irrwahn Grausewitz, Oct 10, 2003
    #5
  6. (Dave Vandervies) wrote:

    >Tim <> wrote:

    <SNIP>
    >>7 int main(void)
    >>8 {
    >>9 int num;
    >>
    >> ...........num defined in code........
    >>
    >>10
    >>11 Stationers stats[num];
    >>12 }
    >>
    >>The error message says "constant expression required" and highlights
    >>line 11. I want to declare it dynamically during runtime, could
    >>someone explain how to do this please.

    >
    >Uhmm... what language are you trying to write this code in?
    >
    >If you're using C99, what you have here should work, since arrays are
    >allowed to have lengths that aren't known until run-time.
    >
    >If you're using C90, you're not allowed to declare a new variable (like
    >the array) after non-declaration stuff (like assigning a value to num),
    >so once you fill in the blanks your code will still be broken no matter
    >how you declare the array. Instead, you'd need to declare a pointer at
    >the beginning of the block and, once you've decided how many elements
    >you want, use malloc to allocate memory for it:
    >--------
    >#include <stdlib.h>
    >
    >/*Define and typedef the Stationers struct here*/
    >
    >int main(void)
    >{
    > int num;
    > Stationers *stats;
    >
    > /*Decide on a value for num here*/
    >
    > stats=malloc(num * sizeof *stats);

    /* check malloc() return value here! */
    >
    > /*I assume you'll want to do something with stats here*/
    >
    > free(stats);

    return 0;
    >}

    <SNIP>
    --
    Irrwahn
    ()
    Irrwahn Grausewitz, Oct 10, 2003
    #6
  7. Noah Roberts <> wrote:

    >Tim wrote:

    [ some code restored ... ]
    >> 7 int main(void)
    >> 8 {
    >> 9 int num;
    >> ...........num defined in code........
    >> 10
    >> 11 Stationers stats[num];
    >> 12 }
    >>
    >> The error message says "constant expression required" and highlights
    >> line 11. I want to declare it dynamically during runtime, could
    >> someone explain how to do this please.

    >
    >Stationers *stats = (Stationers*)malloc(num * sizeof(Stationers));


    Better:

    Stationers *stats = malloc(num * sizeof *stats);

    (The cast to is not only unnecessary, it may hide the failure of not
    including stdlib.h; sizeof *stats has the advantage that one does not
    have to change the malloc expression if the type of stats ever changes.)

    But still this won't work in pre-C99 (in this special case): you define
    a variable in another place than the beginning of a block. Or, if you
    intended to put above line at the top of main(), you don't know the
    value for num, as it has to be calculated yet.

    So, there's no way around splitting the line up into:

    /* goes to top of main(): */
    Stationers *stats;

    /* after num has been calculated: */
    stats = malloc(num * sizeof *stats);

    Regards
    --
    Irrwahn
    ()
    Irrwahn Grausewitz, Oct 10, 2003
    #7
  8. "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

    >"Tim" <> wrote in message
    >news:...
    >> Why won't the declaration of a struct array work if I do it like this:

    >...
    >> 7 int main(void)
    >> 8 {
    >> 9 int num;
    >>
    >> ...........num defined in code........
    >>
    >> 10
    >> 11 Stationers stats[num];
    >> 12 }
    >>
    >> The error message says "constant expression required" and highlights
    >> line 11. I want to declare it dynamically during runtime, could
    >> someone explain how to do this please.

    >
    >This code is actually valid if your compiler implements the 1999
    >C standard. Prior to that, array variables are indeed required
    >to be of a size known at compile time.
    >
    >The backwards-compatible way to do what you want is to use:
    > Stationers* stats = (Stationers*)malloc(num*sizeof(Stationers));


    Better:

    Stationers *stats = malloc(num * sizeof *stats);

    (The cast is not only unnecessary, it may hide the failure of not
    including stdlib.h; sizeof *stats has the advantage that one does not
    have to change the malloc expression if the type of stats ever changes.)

    But still this won't work in pre-C99 (in this special case): you define
    a variable in another place than the beginning of a block. Or, if you
    intended to put above line at the top of main(), you don't know the
    value for num, as it has to be calculated yet.

    So, there's no way around splitting the line up into:

    /* goes to top of main(): */
    Stationers *stats;

    /* after num has been calculated: */
    stats = malloc(num * sizeof *stats);

    > ... use stats as if it were an array of size num ...
    > free(stats); // don't forget this prior to exit !
    >


    Regards
    --
    Irrwahn
    ()
    Irrwahn Grausewitz, Oct 10, 2003
    #8
  9. "Irrwahn Grausewitz" <> wrote in message
    news:...
    > int main( void )
    > {
    > int num;
    > Stationers *stats;
    >
    > /* calculate value for num, e.g: */
    > num = 42;
    >
    > stats = malloc( num * sizeof *stats );
    > if ( stats == NULL )
    > {
    > fprintf( stderr, "Memory allocation error." );
    > return EXIT_FAILURE;
    > }
    >
    > /* do something with stats, e.g: */
    > stats[ 7 ].pens = 6;
    > stats[ 7 ].pencils = 9;


    add:
    free( stats );

    > return EXIT_SUCCESS;
    > }


    Yes, the memory will be reclaimed at program exit on
    any decent OS, but it is a good habit to always free
    the memory that you allocate. (e.g. in case the code
    gets moved into a loop or another function...).

    Cheers,
    Ivan
    --
    http://ivan.vecerina.com
    Ivan Vecerina, Oct 11, 2003
    #9
  10. "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

    >"Irrwahn Grausewitz" <> wrote in message
    >news:...
    >> int main( void )
    >> {
    >> int num;
    >> Stationers *stats;
    >>
    >> /* calculate value for num, e.g: */
    >> num = 42;
    >>
    >> stats = malloc( num * sizeof *stats );
    >> if ( stats == NULL )
    >> {
    >> fprintf( stderr, "Memory allocation error." );
    >> return EXIT_FAILURE;
    >> }
    >>
    >> /* do something with stats, e.g: */
    >> stats[ 7 ].pens = 6;
    >> stats[ 7 ].pencils = 9;

    >
    >add:
    > free( stats );
    >
    >> return EXIT_SUCCESS;
    >> }

    >
    >Yes, the memory will be reclaimed at program exit on
    >any decent OS, but it is a good habit to always free
    >the memory that you allocate. (e.g. in case the code
    >gets moved into a loop or another function...).


    Good point.

    >
    >Cheers,
    >Ivan


    Regards
    --
    Irrwahn
    ()
    Irrwahn Grausewitz, Oct 11, 2003
    #10
  11. Noah Roberts wrote:
    > Tim wrote:
    > Stationers stats[num];
    >
    >> 12 }
    >>
    >> The error message says "constant expression required" and highlights
    >> line 11. I want to declare it dynamically during runtime, could
    >> someone explain how to do this please.

    >
    >
    > Stationers *stats = (Stationers*)malloc(num * sizeof(Stationers));


    Or, better (losing the spurious cast):

    Stationers *stats = malloc(num * sizeof *stats);

    --
    Allin Cottrell
    Department of Economics
    Wake Forest University, NC
    Allin Cottrell, Oct 11, 2003
    #11
  12. Tim

    Tim Guest

    Cheers for the help, I'm now using the malloc function and its working well.
    Tim.
    Tim, Oct 11, 2003
    #12
    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. Chris Fogelklou
    Replies:
    36
    Views:
    1,345
    Chris Fogelklou
    Apr 20, 2004
  2. Daniel Rudy
    Replies:
    7
    Views:
    439
    Daniel Rudy
    Mar 31, 2006
  3. Ehud Shapira
    Replies:
    20
    Views:
    1,099
    Ehud Shapira
    Jun 30, 2007
  4. slocum
    Replies:
    3
    Views:
    497
    slocum
    Apr 11, 2008
  5. Tuan  Bui
    Replies:
    14
    Views:
    461
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page