1

Array needs size to be defined at compile time. Is there any possibility to define the size of array at runtime using malloc or whatever?

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • At compile time or at run time? Your caption doesn't match your question body? – Mario May 18 '14 at 09:09
  • Say what you've tried and show some effort is possible. – Brandin May 18 '14 at 17:12
  • How do the existing answers not answer your question? – Keith Thompson May 30 '14 at 17:47
  • @Mario: Actually, I think the question is clear enough. The language restricts array sizes to values that can be determined at compile time (that's what the first sentence in the body of the question refers to). The OP *wants* to be able to specify an array size at run time. – Keith Thompson May 30 '14 at 17:48
  • Can you give some examples of how you would like to use such a feature? – R Sahu May 30 '14 at 18:02
  • Do you really mean standard C? This would be ISO/IEC 9899:2011 aka C11 which has replaced the obsolete C99 standard and has VLAs, or are you looking for an ISO C90 (ANSI C89) solution. – CB Bailey May 30 '14 at 18:11
  • What exactly is wrong with the answers that made you start a bounty? Why aren't you happy with the `malloc` solution? – Filipe Gonçalves May 30 '14 at 21:23

6 Answers6

6

This is entirely possible and very common. The right tool for the job is the malloc() function. This allows you to dynamically create arrays of any size at runtime. One example is to create an array at runtime with a size specified by the user.

int main(int argc, const char **argv) 
{
    printf("How long should the dynamic array be?");

    int length;
    scanf("%d", &length);

    // dynamically create the array with malloc

    int *array = malloc(sizeof(*array) * length);

    return 0;
}

This array (pointer to int) can be used just like any other array, accessing its values with the [] operator.

int fifthValue = array[4]; // assumes array was malloc()'d with at least 5 mem slots.

When you are done using this dynamically created array, use the free() function to give its memory back to the program.

free(arr);

A second alternative to malloc() is the calloc() function. Because the block of memory returned by malloc() is not always initialized, it may contain garbage data. If this is not desirable, the calloc() function can be used. calloc() will initialize all of the elements of the returned memory to 0 for you. The call to calloc() is slightly different than the call to malloc().

int main(int argc, const char **argv) 
{
    printf("How long should the dynamic array be?");

    int length;
    scanf("%d", &length);

    // dynamically create the array with calloc and initialize it to 0

    int *array = calloc(length, sizeof(*array));

    return 0;
}

In conclusion, the malloc() and free() functions are perfect for creating dynamic arrays in C. Remember to always call free() on memory that you reserved with malloc() (or calloc()).

Brian Tracy
  • 6,801
  • 2
  • 33
  • 48
1

To define the size of an array at compile time, you're able to use preprocessor macros for example to create a constant expression that can be updated at one position:

#define ARR_LEN 50

char array_one[ARR_LEN];
char array_two[ARR_LEN];

If you want to determine the actual length at run time, then you'll have to use dynamic memory allocation:

int arr_len = <user-input>;

char *array_one = (char*)malloc(sizeof(char) * arr_len);

// use the array

free(array_one);
Mario
  • 35,726
  • 5
  • 62
  • 78
  • You can't necessarily make it a one liner based on where the variable is assigned/used. Or anything else I missed? – Mario May 18 '14 at 09:21
  • 6
    That declaration is better written as `char *array_one = malloc(arr*len * sizeof *array_one);`. It's not necessary to cast the result of `malloc`; the `void*` result will be implicitly converted to the required pointer type, and the cast can mask errors in some cases. Using `sizeof *ptr_var` rather than `sizeof (element_type)` makes the code more robust if the element type is changed later. And you should always check whether `malloc` failed (which it reports by returning a null pointer). – Keith Thompson May 30 '14 at 17:50
1

VLA's are a c99 feature.. and not available in ANSI C / C89 / C90 whatever you want to call it.

but VLA's introduce complexity that I don't like anyway, so in std C it is very common to do the following: (create a contiguous chunk of memory, which is just like a C array on the heap then access it by dereferencing the pointer, or directly with array syntax, both are equivalent and ok)

typedef struct
{
    int a;
    int b;
}MyStruct;

int main(int argc, const char * argv[])
{
    size_t numberOfElements = 5;
     //this will create a buffer numberOfElements * sizeof(MyStruct) in size and init each byte to 0;
    MyStruct * myAlmostArray = calloc(sizeof(MyStruct),numberOfElements);

    //do Stuff
    int i;
    for(i=0;i<numberOfElements;i++)
    {
        //gets the array (not needed in this example)
        MyStruct s = myAlmostArray[i];
        s.a = 3;
        s.b = i;
        //write the stack array back to the heap allocated psuedo array
        myAlmostArray[i] = s;

        //or slightly different example where you mutate the heap memory directly
        myAlmostArray[i].a = 3;
        myAlmostArray[i].b = i;

        //or the same thing written differently
        MyStruct * m = myAlmostArray + i;
        m->a = 3;
        m->b = i;
    }
    // free the memory
    free(myAlmostArray);
}
Grady Player
  • 14,399
  • 2
  • 48
  • 76
1

As other answers specified that, you can do that using malloc function to create a mxn matrix1 of ints.

int **matrix = malloc(m * sizeof(int *));
for(int i = 0; i < n; i++)
    matrix[i] = malloc(n * sizeof(int));  

Another way to do this is, though it is not dynamic nor efficient but make impression that it is dynamic:

#define m 100
#define n 100
//...

int main()
{
    int arr[m][n], row, col;
    scanf("%d %d", row, col);
    arr[row][col];
    //...
}  

1 Note that although it seems that you are creating an array, but the arrays and pointers are two different types. Arrays are not pointers and pointers are not arrays.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
0

An equivalent implementation to dynamic sized arrays can be achieved using alloca. This function allocates space on system stack in the stack frame of the current function as if it was a local variable. So, for example:

void fun(int i) {
   int a[i];
   ...
}

would be implemeted as:

void fun(int i) {
   int *a = alloca(i * sizeof(int));
   ...
}

Allocated space is "freed" at function return. alloca is not POSIX conforming, however.

Marian
  • 7,402
  • 2
  • 22
  • 34
0

You can use calloc , malloc or realloc as per your requirements. They are explained clearly here.

The malloc function allocates n bytes of memory, suitably aligned for storage of any type. This pointer is suitable for passing to free, which deallocates it, or realloc, which changes its size (and may move it to a different location). calloc allocates nmemb*size bytes, as if by malloc, and sets them to all bits zero.
It should be noted that all bits zero is not necessarily a valid null pointer or floating point 0 so calloc cannot be relied upon to correctly initialise all data types.

Here are some code samples

#include<stdlib.h>
/* 
    some code
*/
n = some_calculation() ; // array size generated at runtime
// data_type is the type of the array eg. int or struct
//using calloc ,it will set allocated values to zero or NULL as per their data_type
data_type *array = calloc(n,sizeof(data_type)) ;
// using malloc , it will only allocate adresses, they may contain garbage values
data_type *array = (data_type *)malloc(n);
// using realloc
array = (data_type *) realloc(array, new_n);
// after you have used your array , you can free the memory allocated
free(array);    
Nishant
  • 2,571
  • 1
  • 17
  • 29