Home > Mobile >  Integer array size in C without using dynamic memory allocation
Integer array size in C without using dynamic memory allocation

Time:11-24

I need to declare an array of structures with size symbolnum, but because symbolnum is variable C will produce an error when i write the following code:

extern int symbolnum;

struct SymbTab stab[symbolnum];

I already tried:

extern int symbolnum;
const int size = symbolnum;
struct SymTab stab[size];

Is there a way to achieve this without using dynamic memory allocation functions like malloc() or initializing the size of array using a very big number?

CodePudding user response:

C11 and later permit variable-length arrays as an optional feature. C99 permitted them as a mandatory feature. However, in no case are VLAs permitted at file scope, which appears to be what you are trying to achieve.

And file-scope VLAs wouldn't make sense in light of C semantics anyway. Objects declared at file scope have static storage duration, meaning that they come into existence at or before the beginning of program execution, and live until program termination. That means the array length is needed before the variable can take anything other than its initial value (which is zero or an integer constant expression), so one might as well just use that initial value directly.

Additionally, some C implementations (notably MSVC) never implemented VLAs even when C99 was the current standard, and have no intention to do so now that the feature is optional in the current standard.

So,

Is there a way to achieve this without using dynamic memory allocation functions like malloc() or initializing the size of array using a very big number?

It depends a bit on your exact needs (and on your C implementation), but likely not. One possibility would be to use a local VLA an main(), or in some other function whose execution encompasses the whole need for the array. If your C implementation supports it them you could declare a VLA there, and pass around a pointer to that. But note well that if the upper bound on the number of elements you need is really "a very large number" then this is unlikely to be suitable. VLAs are typically allocated on the stack, which puts a relatively tight bound on how large they can be.

CodePudding user response:

The size of global arrays must be fixed at compile time. VLAs are only allowed inside of functions.

If the value of symbolnum isn't known until runtime, you'll need to declare stab as a pointer type and allocate memory for it dynamically.

Alternately, if the array doesn't take up more than a few 10s of KB, you can define the VLA in the main function and set a global pointer to it.

CodePudding user response:

"Is there a way to achieve this without using dynamic memory allocation functions like malloc() or initializing the size of array using a very big number?"

If you can use variable length array (VLA), then yes it can be done. The following illustrates one way...

With a struct definition in global space, (eg, top of .c file, or in .h file) local array instances of that struct can be created using a VLA, keeping in mind the stipulations mentioned in the link for using VLA. The VLA struct array can then be passed as a function parameter, to either be used in the called function, or to be updated and returned, just as any other function parameter is used. Here is a simple example:

//define either at top of .c file in file global space
//or in a header file that is included in any .c.  Then
//the typedef num_s can be used to create instances where needed
//
typedef struct {
    int iVal;
    double dVal;
} num_s;

void populate_struct(size_t size, num_s *arr);

int main(void)
{
    size_t size = 0;//note, this can come from anywhere.  
                    //i.e. an .ini file, a database read, etc.
                    //User input is used here for simple example
                    // of dynamically sizing array
    printf("Enter size of struct array:\n");
    scanf("%zu", &size);
    num_s arr[size];//dynamically sized array of num_s
    memset(arr, 0, sizeof(num_s) * size); //initialize
    //note size variable must be included as parameter
    populate_struct(size,  arr);//pass as function argument and update values
   for(int i=0; i < size; i  )//demo updated values
   {
       printf("%d, %lf\n", arr[i].iVal, arr[i].dVal);
   }
    
    return 0;
}

//simple function to demo form of parameters
//note size parameter is passed first
void populate_struct(size_t size, num_s *arr)
{
   for(int i=0; i < size; i  )
   {
       arr[i].iVal = i;
       arr[i].dVal = 1.0*i;
   }
}
  • Related