ANSI C Program: How to initialize numeric array when length is determined when program runs?

Go To StackoverFlow.com

0

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.

2012-04-04 20:59
by ggkmath
Rather than -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
Oh, good to know, thanks - ggkmath 2012-04-04 21:26
I'm assuming the -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
What is the reason for -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


4

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
2012-04-04 21:00
by pmr
I agree, you need to use malloc to dynamically allocate the memory space that the array will be using - Travis J 2012-04-04 21:01
Thanks, I know to use malloc. But, I'm assume all variables must be initialized before any code is executed. What value would I enter for the size to preallocate memory, if this size is only known after some of the code executes - ggkmath 2012-04-04 21:03
@ggkmath How can you preallocate (what does that mean anyway) when you don't know how much to preallocate - pmr 2012-04-04 21:05
You can initialize the pointer to NULL - pmg 2012-04-04 21:13
@pmg I added that to the example although it serves no real purpose here. Probably the 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
@ggkmath: You don't have to hard-code the value being passed to 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
Oh, I see, one can declare the variable 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
@ggkmath: Yes, but 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


2

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);
2012-04-04 21:02
by Joachim Isaksson


1

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)); 
2012-04-04 21:09
by Richard J. Ross III
I didn't think in ANSI C that one could declare variables in the middle of the program - ggkmath 2012-04-04 21:11
alloca is not in Standard - pmg 2012-04-04 21:14
@ggkmath correct, but GCC compiled with -ansi still allows it - Richard J. Ross III 2012-04-04 21:14
@pmg added a note about that to the answer, thanks for correcting me - Richard J. Ross III 2012-04-04 21:16


1

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.

2012-04-04 21:55
by John Bode
Thanks for the expanded answer John. I originally coded using gcc 4.4.4 which isn't C99 compatible. Now I'm using gcc 4.4.6 with the same code, but retaining the original 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
Ads