holy
holy

Reputation: 632

Array declaration in C

How to use the arguments of a function to declare an array inside the function?

My code is:

double function_2(int a)
{
  int t[a];
}

An error occurs:

Expression must have a constant value.

Upvotes: 1

Views: 451

Answers (6)

Mike Kwan
Mike Kwan

Reputation: 24477

C99 has an extension for variable length arrays. If you compile your code with the following command, it will work:

gcc -std=gnu99 lala.c -o lala

If you are using VC++, variable length arrays are not present because the standard it uses is C89 with a few features of C99 (not including variable length arrays).


Since you mention compiling with VC++ I will add a few notes:

  • Make sure the code is being compiled as C by changing the extensions of the source files to be .c instead of .cpp
  • Since variable length arrays are not supported as I stated earlier, you will have to use a dynamic approach (see below).

Using dynamic allocation to do the equivalent of what you're attempting:

int * t = malloc(a * sizeof(int))

If you are using dynamic allocation and want to return the array, you can do so by having the function return a int * and then returning t. However, if you do this it is common return the length of the array too (unless it is a fixed, known length). Common techniques used for returning this length are:

  • Providing a separate function which does nothing other than check how big the array would need to be for the calculation and return it.

For example:

// Returns number of entries in the Lala array returned from b()
int GetNumLalaEntries(void);

// Function b which returns an array.
int * b(void)
{
  int * lala = malloc(5 * sizeof(int *));
  ...
  return lala;
}

In the above case, GetNumLalaEntries returns 5 always but if this number was dynamic, that would need to be generated from some internal synchronization information.

  • Use the first technique and have the caller pass in the array. The neat thing with this is that the caller then deals with both allocation and deallocation of the array.

For example:

// We are passing in the array this time.
void b(int * lala)
{
  ... // Do whatever you need with lala
}

int main(void)
{
  int * lala = malloc(GetNumLalaEntries() * sizeof(int *));
  b(lala);
  return 0;
}
  • Returning a struct instead which has both the array pointer and array size.

For example:

struct lala_encapsulation {
  int * lala;
  int   lala_entries;
};

struct lala_encapsulation b(void)
{
  struct lala_encapsulation le;
  le.lala_entries = 5;
  le.lala         = malloc(le.lala_entires * sizeof(int *));

  return le;
}

The last method allows you to return the whole array by wrapping it in a struct which can be returned by value.

Upvotes: 2

ouah
ouah

Reputation: 145919

Your code is perfectly valid C code.

You are using a VLA (variable length array). This is a c99 feature and you have to insure your compiler supports c99 code.

If you are using gcc, by default gcc is set to -std=gnu89 which is C89 + GNU extensions. Use -std=c99 or -std=gnu99 with gcc to compile your program.

If you are using MSVC, it unfortunately does not support c99 so you cannot use a c99 feature with this compiler.

EDIT:

If your compiler does not support VLA you can use dynamic memory allocation instead:

#include <stdlib.h>

double function_2(int a)
{
    // Allocate array object
    int *t = malloc(a * sizeof *t);

    if (!t) {
        // Handle malloc errors
    }

    // Write your program here: ...

    // Free array object
    free(t);
}

Upvotes: 6

Flynch
Flynch

Reputation: 84

double function_2(int a)
{
  int * t = (int*)malloc(sizeof(int)*a);
  for(int i = 0; i<a; i++)
  {
    // do your work here, accessing t like an array
    t[i]=...
  }
  free(t);

...
}

Upvotes: 1

stefan bachert
stefan bachert

Reputation: 9624

You have to use the heap (malloc/free)

#include<stdlib.h>

double function_2(int a)
{
 ....
  int *t = (int*) malloc (sizeof(int) *a);
  t [1] = 1; // but check if array is large enough
  ...
  free (t);
  ...
  return 0.0;
}

Upvotes: 1

Thiago Vieira
Thiago Vieira

Reputation: 128

Instead of array, you should use memory allocation and use it like a array for iteration or other use.

Upvotes: 1

Hiren H Patel
Hiren H Patel

Reputation: 167

You can not assign it directly. You have to declare it of fixed constant.

Otherwise use the concept of pointer.

Upvotes: 1

Related Questions