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.

ggkmath
  • 4,188
  • 23
  • 72
  • 129
  • 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 Apr 04 '12 at 21:25
  • I'm assuming the `-pedantic` is useful for portability, but would be interested if there's other reasons why "gcc"isms are unwanted. – ggkmath Apr 04 '12 at 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.html – pmg Apr 04 '12 at 21:47

4 Answers4

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
Community
  • 1
  • 1
pmr
  • 58,701
  • 10
  • 113
  • 156
  • I agree, you need to use malloc to dynamically allocate the memory space that the array will be using. – Travis J Apr 04 '12 at 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 Apr 04 '12 at 21:03
  • 1
    @ggkmath How can you preallocate (what does that mean anyway) when you don't know how much to preallocate? – pmr Apr 04 '12 at 21:05
  • @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 Apr 04 '12 at 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 Apr 04 '12 at 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 Apr 04 '12 at 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 Apr 04 '12 at 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);
Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
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)); 
Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
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.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • 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 Apr 04 '12 at 22:22