Necesito declarar una matriz de estructuras con tamaño symbolnum , pero debido a que symbolnum es variable C, se producirá un error cuando escriba el siguiente código:
extern int symbolnum; struct SymbTab stab[symbolnum];Ya probé:
extern int symbolnum; const int size = symbolnum; struct SymTab stab[size]; ¿Hay alguna manera de lograr esto sin usar funciones de asignación de memoria dinámica como malloc() o inicializar el tamaño de la matriz usando un número muy grande?
El tamaño de las matrices globales debe fijarse en el momento de la compilación. Los VLA solo se permiten dentro de las funciones.
Si el valor de symbolnum no se conoce hasta el tiempo de ejecución, deberá declarar stab como un tipo de puntero y asignarle memoria dinámicamente.
Alternativamente, si la matriz no ocupa más de unas decenas de KB, puede definir el VLA en la función main y establecer un puntero global.
C11 y versiones posteriores permiten arreglos de longitud variable como característica opcional. C99 los permitió como una característica obligatoria. Sin embargo, en ningún caso se permiten los VLA en el alcance del archivo, que parece ser lo que está tratando de lograr.
Y los VLA de alcance de archivo no tendrían sentido a la luz de la semántica C de todos modos. Los objetos declarados en el alcance del archivo tienen una duración de almacenamiento estática, lo que significa que se crean al comienzo de la ejecución del programa o antes, y viven hasta la finalización del programa. Eso significa que se necesita la longitud de la matriz antes de que la variable pueda tomar cualquier valor que no sea su valor inicial (que es cero o una expresión constante entera), por lo que también se podría usar ese valor inicial directamente.
Además, algunas implementaciones de C (especialmente MSVC) nunca implementaron los VLA, incluso cuando C99 era el estándar actual, y no tienen intención de hacerlo ahora que la característica es opcional en el estándar actual.
Asi que,
¿Hay alguna manera de lograr esto sin usar funciones de asignación de memoria dinámica como
malloc()o inicializar el tamaño de la matriz usando un número muy grande?
Depende un poco de sus necesidades exactas (y de su implementación de C), pero probablemente no. Una posibilidad sería usar un VLA local en main() , o en alguna otra función cuya ejecución abarque toda la necesidad del arreglo. Si su implementación de C lo admite, podría declarar un VLA allí y pasar un puntero a eso. Pero tenga en cuenta que si el límite superior del número de elementos que necesita es realmente "un número muy grande", es poco probable que sea adecuado. Los VLA generalmente se asignan en la pila, lo que pone un límite relativamente estrecho sobre cuán grandes pueden ser.
"¿Hay alguna manera de lograr esto sin usar funciones de asignación de memoria dinámica como malloc() o inicializar el tamaño de la matriz usando un número muy grande?"
Si puede usar una matriz de longitud variable (VLA), entonces sí, se puede hacer. Lo siguiente ilustra una forma...
Con una definición de struct en el espacio global (p. ej., la parte superior del archivo .c o en el archivo .h), se pueden crear instancias de matrices locales de esa struct usando un VLA, teniendo en cuenta las estipulaciones mencionadas en el enlace para usar VLA. La matriz de struct VLA se puede pasar como un parámetro de función, ya sea para usarse en la función llamada o para actualizarse y devolverse, tal como se usa cualquier otro parámetro de función. Aquí hay un ejemplo simple:
//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 SymbTab{ int iVal; double dVal; } SymbTab_s; void populate_struct(size_t symbolnum, SymbTab_s *stab); int main(void) { size_t symbolnum = 0;//(using size_t). note, as you describe, this //comes after flex analysis normally, but for //this demo user input is used for simple // example of dynamically sizing array. printf("Enter symbolnum of struct array:\n"); scanf("%zu", &symbolnum); SymbTab_s stab[symbolnum]; //dynamically sized array of SymbTab_s memset(stab, 0, sizeof(SymbTab_s) * symbolnum); //initialize new array populate_struct(symbolnum, stab); //pass as function argument and update values //demo updated values for(int i=0; i < symbolnum; i++) { printf("%d, %lf\n", stab[i].iVal, stab[i].dVal); } return 0; } //simple function to demo form of parameters //note size parameter is passed first void populate_struct(size_t symbolnum, SymbTab_s *stab) { for(int i=0; i < symbolnum; i++) { stab[i].iVal = i; stab[i].dVal = 1.0*i; } }