0

I'm writing a program in C which I want to read an array length, and create an array of that size. However, C does not support variable-lengthed arrays, so I was wondering how I could do this. I do not want to change my compiler settings.

I was thinking about somehow using preprocessor directive to my advantage, but I have not been able to do so. Pretty much, I have an integer variable containing my desired size, and I would like to declare the array with 0's. Also, I do not want to use malloc/other dynamic array methods.

This might seem basic, but I have been struggling to do this for some time. If it matters, I am receiving the array size through I/O.

15
  • Sorry, I forgot to specify - I want to do this without malloc Commented Jun 10, 2019 at 21:44
  • 1
    You can't do it without malloc. Either you define a size compile time or allocate memory runtime. Commented Jun 10, 2019 at 21:45
  • I am receiving the integer through I/O. Does that matter? Commented Jun 10, 2019 at 21:45
  • 1
    No - if you don't know the size until runtime, malloc or one of its ilk is your only way of dynamic allocation. Commented Jun 10, 2019 at 21:48
  • 1
    BTW: C does support VLAs (just C++ doesn't)... Commented Jun 10, 2019 at 21:50

5 Answers 5

4

There are several possible solutions, none of which satisfy all of your requirements.

A call to malloc is the obvious solution; that's what it's for. You've said you don't want to use malloc, but you haven't explained why.

C does support variable-length arrays -- more or less. VLAs did not exist in C90, were introduced in C99, and were made optional in C11. So if you want portable code, you can't assume that they're supported. If they are, you can do something like this:

int size;
// get value of size from input
int vla[size];

There are some restrictions. If there isn't enough memory (stack size can be more restrictive than heap size), the behavior is undefined. On the other hand, the same is true for ordinary fixed-size arrays, and VLAs can let you allocate a smaller amount of memory rather than assuming a fixed upper bound. VLAs exist only at block scope, so the object will cease to exist when control leaves the enclosing block (typically when the function returns).

You could define an array (probably at file scope, outside any function definition) that you know is big enough for your data. You'll have to specify some upper bound. For example, you can define int arr[10000]; and then reject any input bigger than 10,000. You could then use an initial subset of that array for your data.

You say you want to create a "variably-sized array", but you "do not want to use malloc/other dynamic array methods". It sounds like you want to create a dynamic array, but you don't want to create a dynamic array. It's like saying you want to drive a screw, but you don't want to use a screwdriver.

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

Comments

0

May I ask: why are you allergic to malloc()?

The reason I ask is that many attempts to define a safe profile for C propose that malloc is the source of all evil. In that case:

int *arr;
arr = mmap(0, sizeof *arr * N, PROT_READ|PROT_WRITE, MAP_PRIVATE, -1, 0);

Comments

0

What you can do is read the array length, and then generate the source code of a program:

fprintf(outfile, "int main(void) { static int arr[%d]; ...}\n", size);

Then execute the compiler on the generated program (e.g. using the system function), and run the resulting executable.

1 Comment

You're assuming a compiler is available on the target system.
0

Any language which supports variable length arrays uses dynamic memory allocation mechanism underneath to implement the functionality. 'C' does not have a syntactic sugar which supports true variable length arrays, but it provides all the mechanics needed to mimic one.

malloc, realloc, free, and others can easily be used to handle dynamic allocations and deallocations for arrays of any size and types of elements. You can allocate data in memory and use a pointer to return the reference to caller functions or pass to other functions. ('C' VLAs on the other hand are of limited use and cannot be returned to the caller if allocated on stack).

So, your best option (unless you are in embedded software development) is to start using 'c' dynamic memory allocation.

Comments

0

However, C does not support variable-lengthed arrays,

Wrong. This is perfectly valid C code:

#include <stdio.h>

int main(void)
{
    int size;
    scanf("%d", &size);
    int arr[size];
}

It's called VLA (variable length array) and has been a part of C since 1999. However, it's optional from C11, but big compilers like clang and gcc will never remove them. At least not in the foreseeable future.

9 Comments

which might, under the covers, call malloc. You can’t know that it does, doesn’t, and have no mechanism to detect failure. In all reasonable terms, it isn’t C.
Unfortunately (1) it's a part that had to be backpedaled, becoming optional and (2) the code basically allocates as much stack as the input says, without any way of detecting a problem if that is too much. So "perfectly valid" is a bit of a stretch.
@mevets: It's very unlikely to use malloc. The lifetime ends at the end of the innermost enclosing block. VLAs are clearly intended to be allocated on the stack. An implementation could use malloc to allocate VLAs, but it would have to generate additional code to call free at the right time, regardless of how the block is exited (goto, longjmp, etc.). Incidentally, VLAs were introduced in C99 and made optional in C11.
It is not spurious at all. The authors of C made very sure that the language itself contained no “surprises” -- no searches, allocations or anything of the sort. The language committee, free of any accountability, made a terrible choice to introduce a facility that made no sense with respect to the nature or intent of the language. Further, they enabled future ones to continue the tradition of bad decisions, up to and including the inane definition of atomics. Spurious; no. They are incompetent, and should be stripped.
@mevets: void func(void) { char big_array[1000000]; /* ... */ } -- There's a C construct that can cause your program to fault, with no way for you to intercept, recover, or avoid it. Yes, that sounds like C.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.