1

I get this error when I run my code:

error: invariably modified 'Square_Toys' at file scope.

There is a variable defined globally at the top of my code called NumOfToys, and then I define my array Toy* Square_Toys[NumOfToys] following it after. The NumOfToys is dependent on what the user inputs, so I cannot define the size of the array beforehand :(

How I can get rid of this error?

int NumOfToys; // <------- This is entered through the user running the programin the terminal
struct toy * Square_Toys[NumOfToys];
5
  • 4
    It would help to actually show the relevant code? Instead of just the small snippets. Commented Oct 6, 2013 at 17:09
  • 1
    dynamically allocate the array. What you have done is to create an array of NumOfToys pointers. What you want to do is Toy *Square_Toys = malloc(NumOfToys * sizeof(Toy)) - create an array of NumOfToys objects Commented Oct 6, 2013 at 17:11
  • @Smac89 new is C++ only. The question is tagged c. Commented Oct 6, 2013 at 17:14
  • 1
    Do you really need an array of pointers to struct toy? Or did you really intend to have an array of struct toy? Commented Oct 6, 2013 at 17:19
  • Does it actually say "invariably"? Not "variably"? Commented Aug 13, 2023 at 18:48

3 Answers 3

2

You can't use a direct array in that case. Variable Length Arrays can only be declared in local scope. I.e. if the array size is a run-time value, then you cannot declare such array in file scope. All arrays with static storage duration shall have compile-time sizes. There's no way around it.

If your array has to declared in file scope (BTW, why?), you have to use a pointer instead and allocate memory manually using malloc, as in

int NumOfToys;
struct toy **Square_Toys;

int main()
{
  ...
  /* When the value of `NumOfToys` is already known */
  Square_Toys = malloc(NumOfToys * sizeof *Square_Toys);
  ...
  /* When you no longer need it */
  free(Square_Toys);
  ...
}

Another alternative would be to stop trying to use a file scope variable and switch to a local array instead. If the array size is not prohibitively large, you will be able to use Variable Length Array in local scope.

A third alternative would be an ugly hybrid approach: declare a global pointer, but use a local VLA to allocate the memory

int NumOfToys;
struct toy **Square_Toys;

int main()
{
  ...
  /* When the value of `NumOfToys` is already known */
  struct toy *Local_Square_Toys[NumOfToys];
  Square_Toys = Local_Square_Toys;
  ...
}

But this is here just for illustrative purposes. It is ugly.

Sign up to request clarification or add additional context in comments.

8 Comments

If I put this in my main function, and I have functions above it that call it, I would get a compiler error thats it's not defined correct? Do you know how I can make it so it can be accessed by the other functions, without physically passing it into the functions?
I just want to allocate an array of those toys which will be accessed later on by other functions
@Masterminder: That is true. That means you will have to pass it to those other functions as an argument. This is the proper way to do it. Global variable might seem "easier", but it is really a very poor and lazy way out.
@Masterminder: If you want to allocate an array of toys, why does the code sample in your question declare an array of pointers to toys?
I am declaring an array of pointers to toys, and then later on will allocate memory for each toy
|
0

The NumOfToys is dependent on what the user inputs so I cannot define the size of the array beforehand

Either You can dynamically allocate space for array or use VLA's. For VLA, after user input for NumOfToys declare your array in main.

printf("Enter number of toys: ");
scanf("%d", &NumOfToys);

struct toy * Square_Toys[NumOfToys];    

Comments

0

Size of global array should be constant because the compiler needs to know it in compile time. If you need a dynamic array, allocate it with malloc in runtime:

Toy **Square_Toys;

void foo(void) {
  Square_Toys = malloc(NumOfToys * sizeof(Toy*));

  // do stuff here

  free(Square_Toys);
}

4 Comments

sizeof(Toy) -> sizeof SquareToys[0]. In case the type ever changes.
If I do it like this in my main function and allocate the memory, but I have functions above the main that call it, it would give me an error that Square_Toys is not defined, correct?
The OP code sample requests an array of pointers to Toy, not an array of Toy.
No, you won't get 'Square_Toys not defined' error, but you should allocate the array before you use it. I have updated the code according to the new code snippet in the question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.