karoma
karoma

Reputation: 1558

Dynamically allocating an array of structs

I'm trying to create an array of structs, of which the array size is defined by the user in the program. eg. p[0], p[1], p[2].....

typedef struct
{
int score;
}player;

void main()
{
    int numPlayers;

    printf ("\nEnter number of players (1 - 4)\n");
    scanf ("%d", &numPlayers);

}

I've tried doing it with both

player p[numPlayers];

and

player *p=malloc(numPlayers*sizeof(player));

but both won't compile. Can anyone see what's going wrong here?

Edit: I'm using VS2010. I'm getting "expression must have a constant value" for the first one, and "a value of type "void*" cannot be used to initialise an entity of type "player*" for the second one.

Upvotes: 1

Views: 1662

Answers (2)

Kaz
Kaz

Reputation: 58500

The player p[numPlayers]; approach calls for a "variable length array". This is a feature which appeared in the GNU C dialect many years ago, and was adopted into the C language in 1999. To get that to compile you need a compiler which recognizes this as an extension, or a C99 compiler. Variable Length Arrays have a downside: they are usually implemented by allocating the memory on the stack. There is no way to detect whether or not there is enough memory.

The malloc calling syntax you have is fine:

player *p=malloc(numPlayers*sizeof(player));

However, if you want to write this anywhere in your function, you need to be using a C99 compiler, or a compiler that accepts inter-mingled statements and declarations (like GNU C which has had that as an extension for years before C99 and accepts it by default. In C90, you have to declare the pointer in the block of declarations at the top of the function (or braced statement): player *p = NULL;. Then later, after the number of players is known, assign to it p = malloc ....

You should post the actual program that doesn't compile. Without that we are only guessing!

Moreover, you have some problems.

Firstly, if you want to call malloc, you should include the header <stdlib.h> where malloc is declared.

Secondly, main should return type int not void.

Also, check the return value of scanf. The scanf function is bad for interactive input. For instance if the user hits Enter, scanf keeps waiting for input, looking for those numeric characters, which is unfriendly. scanf also has no error checking in %d. If you enter a number that doesn't fit into the type int the behavior is simply undefined. This type of input handling is only suitable for quick-and-dirty "throwaway" programs written for the author's own use.

Upvotes: 1

Jerry Coffin
Jerry Coffin

Reputation: 490018

One possibility would be that you've forgotten to #include <stdlib.h>. Without a prototype for it, the compiler will assume that malloc returns an int, which won't convert to a pointer without a cast (but don't use a cast -- include the proper header so the compiler knows the return type instead).

Edit: It's unrelated, but FWIW, main should return int, not void.

Upvotes: 1

Related Questions