dynamic declaration of struct array

T

Tim

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.
 
N

Noah Roberts

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
 
I

Ivan Vecerina

Tim said:
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
 
D

Dave Vandervies

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
 
I

Irrwahn Grausewitz

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
 
I

Irrwahn Grausewitz

Tim <[email protected]> wrote:
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>
 
I

Irrwahn Grausewitz

Noah Roberts said:
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
 
I

Irrwahn Grausewitz

Ivan Vecerina said:
Tim said:
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
 
I

Ivan Vecerina

Irrwahn Grausewitz said:
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
 
I

Irrwahn Grausewitz

Ivan Vecerina said:
Irrwahn Grausewitz said:
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
 
A

Allin Cottrell

Noah said:
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);
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top