error C2057: expected constant expression (Can the size of an array in C language be defined when the program is running?)

Can the size of an array be defined at run time?
no. In the definition of an array, the size of the array must be known at compile time, not at run time. For example, if I is a variable, you cannot use I to define the size of an array:
char array[I]; Notvalidc */
supports this definition in some languages, but not in C. If C supported this definition, the stack would become more complex, the overhead of calling functions would be greater, and the program would run significantly slower.
if the size of the array is known at compile time, even if it is a very complex expression, you can define it as long as it can be calculated at compile time. If you want to use an array whose size is not known until the program is running, you can specify a pointer and call the malloc() or calloc() functions to allocate memory space for the array from the heap. Here is an example of an argv array that is copied to the main() function:

[cpp]
view plain
copy

    7.15 cases in row to determine the size of the array, use the pointer and the malloc ()/* A silly program that copies the argv array and all the pointed – to strings. Just for fun, it also deallocates all the copies. */# include & lt; Stdlib. H> # include & lt; String. H> Int main (int arg c, char * * argv) {char * * new_argv; Int I;/* Since argv [0] through argv [arg c] are all valid, the program needs to the allocate room for arg c + 1 Pointers. */new_argv = (char * *) calloc (arg c + l, sizeof (char *));/* or malloc ((arg c + 1) * sizeof (char *)) */printf (” allocated room for % d Pointers starting at % P \ n “, arg c + 1, new_argv);/* now copy all the strings more (argv [0] through argv [arg c – l]) */for (I = 0; i< argc; + + I) {/ * make room for ‘\ 0’ at end, too */new_argv [I] = (char *) malloc (strlen (argv [I]) + l); Strcpy (new_argv [I], argv [I]); Printf (” % d bytes allocated for new_argv [% d] at % P “, “copied \” % s \ \ “n”, strlen (argv [I]) + l, I, new_argv [I], new_argv [I]); } new_ argv [arg c] = NULL:/* To deallocate everything, get rid of the strings (in any order), then the array of Pointers. If you free the array of poiners first, you lose all the reference To t (I = 0); i< argc; + + I) {free (new_argv [I]); Printf (” freed new_argv [% d] at % P \ n “, I, new_argv [I]); Argv [I] = NULL; * * Habit, see note at the end of this example */} free(new_argv); Printf (” Freed new_argv itself at %P\n”, new_argv); Return 0; /* see 16.4 */}

Note: Why does example 7.5 assign NULL after freeing each element in the new_argv array?This is a habit formed on the basis of long practice. After a pointer is released, you can no longer use the data it originally pointed to, or the pointer is “suspended” and no longer points to any useful data. If a pointer is assigned NULL immediately after it is released, the program will not make an error even if it USES the pointer again. Of course, the program may indirectly refer to the null pointer, but such errors can be detected in time while debugging the program. In addition, a
program may still have some original copies of the pointer pointing to the portion of memory that has been freed, which is natural in C programs. In short, although this habit doesn’t solve all problems, it does help.

Read More: