Newbie to C. I'm writing an ANSI C program (on Linux using gcc 4.4.6) and need to know how to initilize a numeric array, such as int or double, where the length of the array is determined when the program is run?
Does ANSI C allow one to declare variable, execute some code (wherein the length is determined), then declare additional variables (e.g. the arrays in question)?
If not, how is this done in practice? Note the program compiles using gcc -ansi ...
switch.
-pedantic
is useful for portability, but would be interested if there's other reasons why "gcc"isms are unwanted - ggkmath 2012-04-04 21:34
-std=c89
(or -ansi
) in the first place? If you're interested in writing standard compliant code every little bit of help from the compiler is helpful. Try, for example, case ranges (case 1 ... 10: break;
). Or see http://gcc.gnu.org/onlinedocs/gcc/C-Extensions.htm - pmg 2012-04-04 21:47
You need to allocate the memory for the array and free it after you are done.
See malloc and free and get one of the beginner books listed here. Attempting to write C without a solid foundation ends in blood, tears and segfaults. Think of the children. Don't do it.
Example to get you started with shooting yourself in the foot:
int* intarray = NULL;
intarray = (int*)malloc(sizeof(int) * 23); // allocate space for 23 intS
malloc
and definition of intarray
are best done in a single statement but that is not significant as well - pmr 2012-04-04 21:17
malloc
, it's a function call like any other. malloc(sizeof(*intarray) * size)
, where size
is a variable that is assigned a value from user input. You also shouldn't cast the return of malloc
in C. You should probably start reading a C book/tutorial - AusCBloke 2012-04-04 21:26
intarray
in the first part of the program, then later, towards the middle of the program, use malloc to allocate memory to intarray
. Since the answer above placed these lines after each other I didn't "see" it. Is that right - ggkmath 2012-04-04 21:32
intarray
is just a pointer and points to the memory allocated by malloc
, the memory isn't allocated to it - AusCBloke 2012-04-04 21:34
To make a dynamic array, you'd instead use a pointer; the usage is pretty much the same, but you need to free() the memory once you're done with it;
int staticArray[10];
int *dynamicArray;
// calculate length of the dynamic array here
int length = 3*4;
dynamicArray = (int*)malloc(length * sizeof(int));
staticArray[4] = 7;
dynamicArray[8] = 5;
free(dynamicArray);
I would recommend alloca
over malloc
if you would like the data allocated on the stack (and if it's available), but malloc will work in most situations.
Note that GCC allows for flexible length arrays, even when compiled with -ansi
, so you can just do this:
int size = 0;
printf("please enter array size: ");
scanf("%i", &size);
data_type data[size];
However, if you must have it dynamically allocated, you can simply replace the last line with this:
data_type *data = alloca(size * sizeof(*data));
Does ANSI C allow one to declare variable, execute some code (wherein the length is determined), then declare additional variables (e.g. the arrays in question)?
As of the 1999 standard, you can mingle declarations and code within a block; prior to that, all declarations within a block had to precede code. To compile for C99, use -std=c99
instead of -ansi
(which is synonymous with -std=c89
). So the following would be legal in C99:
int main(void)
{
int size;
// get the size somehow
int *array = malloc(sizeof *array * size);
...
// don't forget to clean up when you're done
free(array);
}
If you must compile with the -ansi
flag (meaning you must conform to the C89 standard), you'd have to structure your code like so:
int main(void)
{
int size;
int *array;
// get size somehow
array = malloc(sizeof *array * size);
...
free(array);
}
Note that C99 also supports variable length arrays, which allow you to specify the size of an array at run time:
int main(void)
{
int size;
// get size as before
int array[size];
...
}
VLAs are somewhat limited compared to regular arrays (they can't be members of struct or union types, and they can't appear outside of a function), and must be used with care; if you need to allocate a lot of space, use malloc
instead. Their implementation turned out to be complicated enough that the recently-approved 2011 standard gives implementations the option to not support them.
gcc -std=c89
switch to ensure nothing changes. I'm not sure if 4.4.6 is C99 compatible (I'll take a look at it) - ggkmath 2012-04-04 22:22
-ansi
prefer to use a specific language option: currently-ansi
is the same as-std=c89
but it will change sometime ... Also use-pedantic
when using-std=c89
or-std=c99
(or-std=c11
) to prevent "gcc"isms to get into your code - pmg 2012-04-04 21:25