Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - return array of unknown size

Tags:

arrays

c

c99

Suppose I want to write (in C99) the following function:

NAME: primes
INPUT: an integer n > 0
OUTPUT: int array filled with the prime numbers in range [2, n]

How can I return such an array from my function? Is that possible?


Note that I don't want the caller to allocate an n * sizeof(int) array that I'll fill with 0 (composite) and 1 (primes).

I can't just return a pointer to the array, because the caller has no way to know how long the array is:

int * primes(int n)
{
    int * arr = malloc(n * sizeof(int));
    // do stuff
    return arr;
} 

int main(void)
{
    int * arr = primes(100);
    printf("%lu \n", sizeof arr); // prints 8
}

and I can't change the signature like this:

int (*primes(int n))[LENGTH]  

because LENGTH is unknown at compile time.


I read somewhere something like "to return a struct with the array is an horrible idea", and, well... that was my last idea.

What's the best practice in cases like this?

like image 976
Haile Avatar asked Oct 10 '13 16:10

Haile


1 Answers

If the function that you call must decide the actual number of elements that it needs to allocate, you should pass a pointer to the allocated length along with the rest of the parameters, like this:

size_t actual_length;
int *arr = primes(100, &actual_length);
if (arr == NULL) {
    ... // Report an error
}
for (size_t i = 0 ; i != actual_length ; i++) {
    printf("%d\n", array[i]);
}

The primes would then look like this:

int *primes(int count, size_t *actual_length) {
    size_t primes_needed = ...
    int *res = malloc(sizeof(*res)*primes_needed);
    *actual_length = primes_needed;
    // Do calculations, perhaps some reallocs
    // Don't forget to reassign *actual_length = ... on realloc
    ...
    return res;
}
like image 89
Sergey Kalinichenko Avatar answered Nov 10 '22 04:11

Sergey Kalinichenko