0

I would like to extend the solution i found to return an array from a function, so that i have a function that creates an array with a length that's provided to this function.

But now if i call the function like this i get a warning, that ‘length’ is undeclared.

double * my_function(int length)
{
    static double arr[length] = {0};

    return arr;
}

How can this behavior be avoided?

1
  • 1
    Assuming you have a compiler that support variable length arrays, they can not be static. Commented Nov 15, 2013 at 16:41

5 Answers 5

2

If you are going to allocate variable length array, why not use calloc?

double * my_function(size_t length)
{
    double *arr;    
    arr = calloc(length, sizeof *arr);
    return arr;
}

free() the arr once you are done and check if it's NULL before using it.

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

1 Comment

How is freeing the memory handled
2

Static arrays must have a length that is known at compile-time. With ordinary automatic arrays you can specify a variable length, but that is a special C99 feature called "variable-length arrays", or VLA's for short.

Variable-length static arrays are not possible because the storage for them has to be allocated even before your program is allowed to run by the operating system.

Automatic (local) variable-length arrays are possible because it just implies incrementing/decrementing the stack pointer by a variable rather than a constant. It is still a dangerous thing to do, though, because you can easily exceed the available stack space in case of having a larger value as the length.

Comments

1

Look into malloc. The *alloc functions are used to dynamically create arrays. They're created on something called the heap, and when you're programming, you need to make sure that things that are allocated on the heap are cared for properly, or you can start having memory leaks. In your case, you have somewhat taken care of it by making it static. The other major way to do things is to have the caller of the function free the memory when it's done with it.

Your usage should be something like this:

double * my_function(int length)
{
    static double * arr = NULL;
    if (arr == NULL) {
        arr = malloc(length * sizeof(double));
    }
    return arr;
}

Note, by having the static and putting the wrapper around it as I did, this is setting arr up to fit a singleton design.

The non-singleton alternative is:

double * my_function(int length)
{
    static double * arr = NULL;
    if (arr != NULL) {
        free(arr);
    }
    arr = malloc(length * sizeof(double));
    return arr;
}

This one reallocates each time it is called. Any function that saved the return value from my_function would then find it to be out of date.

4 Comments

Strictly speaking, malloc doesn't "create arrays", but instead returns a pointer to an unoccupied contiguous area of memory. In the terms of the C language, the latter is not an array.
Hmm, for the 2nd solution I do not see how it ever shall allocate anything. As far as I understand the code malloc() is never called and NULL is returned always.
The test for NULL is waste of time, as free() is defined to accept NULL, at least from C99 on.
@alk I'm going to leave it (on the bet that compilers would optimize it out since it's a very common construct, or that the one to two machine operations it costs will not be prohibitive), simply because it reads more cleanly to me than static double * arr = NULL; free (arr);
0

First of all, this is not ANSI C (as far as I remember). You cannot declare arrays of size that is not a compile-time constant.

Secondly, this approach is in general considered extremely bad as it implements a function that is not thread-safe. Multiple threads using this function will corrupt each-other's data in this array.

A proper general way is to allocate an array using malloc()/calloc() inside the function. Depending on the problem you are trying to solve and performance requirements, you might consider doing various optimizations to avoid repeated/frequent allocations.

3 Comments

That's what I suspected. Still, for maximum portability I wouldn't bet on this for a while...
So, How many years would you require before we should use functionality of one of the most common C standards now in use? (now 14 years and counting) Also, your comment about thread safety in general considered extremely bad as it implements a function that is not thread-safe is baiting, and of no consequence in the context of OP. (i.e. yes, thread safety is a concern in threaded applications, but not at all an issue in a non-threaded application.). OP indicates no curiosity on that topic.
As many years as it would take for all platforms I'm building the product du jour (last one had to run on a range of UNIX hardware starting with Data General to Solaris/SPARC, AIX/PPC to HP/UX). Good luck ensuring working C99 on all those platforms (and no, "using GCC" was not an option). As for multi-threading, I've encountered lot of written code where author indicated no curiosity in thread safety resulting in horrible bugs.
0

Just out of curiosity, Why didn't you use malloc?

and as mentioned above, since you are declaring a static array so the program will need to know the length of the array at compile time

Comments

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.