1

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.
6
  • possible duplicate of Initializing an array after declaration Commented Apr 3, 2012 at 13:13
  • Are you sure you're using a C compiler? Note that variable length arrays are GNU extensions to C99. Commented Apr 3, 2012 at 13:13
  • @mdm: This is not necessarily a duplicate. The other answers to the question you linked are only suggesting dynamic allocation because the question there explicitly stated C89 where there does not exist the concept of variable length arrays. Commented Apr 3, 2012 at 13:14
  • @mdm: That question is a totally different one. What's asked there is not possible with any compiler I'd know of, while this here is actually standard C. Commented Apr 3, 2012 at 13:14
  • Actually i am using visual studio 2010 and a cpp project but i have changed the properties to compile as C.Is this the problem and how to resolve it ? Commented Apr 3, 2012 at 13:16

6 Answers 6

6

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);
}
Sign up to request clarification or add additional context in comments.

3 Comments

While this is correct, you should also provide the solution (dynamic memory using malloc or more similar to VLAs, using alloca to reserve stack memory). That would make it a perfect answer :)
@NiklasB. I agree the information about malloc is relevant and I'm adding it. Regarding alloca it is a non C standard function.
Yes, but I think it can be used as a workaround in MSVC, which OP uses.
2

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.

4 Comments

Thank you ,I followed the notes.Just a question:if the return type of the function is an array how could i use *t(pointer) to return the array t?
@holy: Edited my answer to include returning the array.
:This is a part of my code:JNIEXPORT jintArray JNICALL Java_MainClass_intArrayMethod (JNIEnv *env, jobject obj, jfloatArray array,jint nb_of_subscribers,jint tags) { jsize len = (*env)->GetArrayLength(env, array); jint *body = (*env)->GetIntArrayElements(env, array, 0);after that i did some modifications to body[] and i want to return all data pointed by body.Is there a method to do this?
I'm not familiar with JNI. You should ask about that in a separate question ;)
1

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

Otherwise use the concept of pointer.

Comments

1

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

Comments

1

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;
}

1 Comment

Although discouraged and deprecated, you can still use the stack for variable-sized allocations via the alloca function, whenever VLA's are not supported.
1
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);

...
}

5 Comments

The idea is right, but i<tis wrong. Should ì < a. ANd you need a cast before malloc
Thank you ,I followed the notes.Just a question:if the return type of the function is an array how could i use *t(pointer) to return the array t?
Not sure that if this is what you want: int * function(...) { (int*)t = (int*)malloc(...); return t ; }
not actually this what i meant : i have in my code : int[]function(int a){ int* t = (int*)malloc(sizeof(int)*a);........} I want to return t which should be an array
Which compiler are you using?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.