7

Is there any way (other than malloc) for creating an array with a size that the user inputs?

6
  • 2
    You need a compiler that supports it and the right options enabled. But be aware of the drawbacks of VLAs before you do it. Commented Sep 11, 2012 at 18:12
  • 9
    Why do you not want to use malloc() ? Commented Sep 11, 2012 at 18:14
  • i want to know if there is any alternative way of doing so. Commented Sep 11, 2012 at 18:16
  • It depends on which C you mean. Commented Sep 11, 2012 at 18:19
  • Well, you had better be very careful about your input then and understand (as @Mystical points out) the ramifications. IMO variable sized arrays are just a bad idea. Commented Sep 11, 2012 at 18:28

5 Answers 5

6

It all depends on the compiler.

Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++. These arrays are declared like any other automatic arrays, but with a length that is not a constant expression. The storage is allocated at the point of declaration and deallocated when the brace-level is exited. For example:

 FILE *
 concat_fopen (char *s1, char *s2, char *mode)
 {
   char str[strlen (s1) + strlen (s2) + 1];
   strcpy (str, s1);
   strcat (str, s2);
   return fopen (str, mode);
 }

See this for more information.

Sign up to request clarification or add additional context in comments.

Comments

2

One way is to use a VLA (C99 defines what are called 'Variable Length Arrays').

Here is an example:

#include <stdio.h>

int use_a_vla (int n)
{
  int vla[n]; /* Array length is derived from function argument.  */

  vla[0] = 10;
  vla[n-1] = 10;

  return 0;
}

int main (void)
{
  int i;

  scanf ("%d", &i); /* User input.  */

  use_a_vla (i);
}

Comments

1

If you don't have VLAs or alloca(), here is an extremely kludgy, but portable, stack-based technique:

int foo(int size)
{
    if (size <= 64*1024)
    {
        unsigned char   arr[64*1024];
        return bar(arr, size);
    }
    else if (size <= 1*1024*1024)
    {
        unsigned char   arr[1*1024*1024];
        return bar(arr, size);
    }
    else if (size <= 64*1024*1024)
    {
        unsigned char   arr[64*1024*1024];
        return bar(arr, size);
    }
    else
        return -1;       // Assume it's too big
}

int bar(unsigned char arr[], int size)
{
    ...your code goes here...
}

int maincode(int size)
{
    // Invoke bar() indirectly, allocating an array
    // on the stack of at least 'size' bytes
    return foo(size);
}

I don't particularly recommend this technique, but it will give you differently-sized blocks of memory allocated on the stack instead of the heap.

Comments

0

Well, this is pedantic, but you can write your own heap management code and call your memory allocation function something other than malloc(). I hope this answer is amusing rather than annoying.

Comments

0

I assume you're trying to avoid malloc because you don't know about realloc.

Essentially, you should be trying to do roughly what the C++ vector does. Once your array grows to a certain size, realloc it to twice its size.

realloc will grow your memory block if possible, and if not possible it will malloc a new one and copy the contents across.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.