How can I make a function which returns an array? I tried this
const int WIDTH=11;
const int HEIGHT=11;
int main() {
char A[WIDTH][HEIGHT];
A=rand_grid(WIDTH,HEIGHT);
return 0;
}
// Initializes a random board.
char[][] rand_grid(int i, int k) {
char* A[i][k];
for(j=0;j<i;++j) {
for(l=0;l<k;++l) {
A[j][l]=ran(10);
}
}
return A;
}
// Returns a random number from the set {0,...,9}.
int ran(int i) {
srand((unsigned int) time(0));
return(rand()%10);
}
You can never return a stack-allocated ("
auto
") variable of something other than a primitive (value) type, andstruct
s of such. For other types, you need to allocate the memory from the heap, usingmalloc()
, or wrap the (fixed-size) array into astruct
.If you're using a fixed-size array, you can model it as a
struct
and use struct-return:This is fine, and should not be more costly than the alternative, of using an explicit pointer:
Since the former case of struct-return can be rewritten (by the compiler) to the latter. This is called return value optimization.
Several things to point out.
First of all, you cannot assign an array object as you do here:
Objects of array type are not modifiable.
Secondly, functions in C cannot return array types. They can return pointers to arrays, though:
The syntax is a little confusing; it reads as
For C89, HEIGHT in the above snippet must be a compile-time constant integral expression (either a macro, a numeric literal, or an arithmetic expression consisting of macros and/or numeric literals). I'm not sure if that's also true for C99.
Based on the snippet you've posted, what you want to do is to take an array you've already allocated and initialize its contents. Remember that in most contexts, an expression of an array type will implicitly be converted to a pointer to the base type. IOW, if you pass an N-element array of T to a function, what the function actually receives is a pointer to T:
For 2-d arrays, it's a little uglier:
This also relies on M being known at compile time, which limits the function's usefulness. What you'd like is a function that can deal with a 2-d array of arbitrary size. The best way I know of to accomplish this is instead of passing a pointer to the array, pass the address of the first element in the array[1], and pass the number of rows and columns as separate parameters:
So your rand_grid function would look something like this:
&A[0][0]
andA
yield the same value (the base address of A), the types of the two expressions are different. The first expression evaluates to a simple pointer to char (char *
), while the second evaluates to a pointer to a 2-d array of char (char (*)[HEIGHT]
).If you really want to do that you can try making the array A static, this way the storage for A is not determined by the scope of function and you can actually return the array(in form of pointer of course).
But this is not a good way to do accomplish what you are trying to achieve, instead pass the array to function
rand_grid
. Thats what pass by address is meant for.All methods of which I am aware to return an array from a function have weaknesses and strengths.
Wrapping in a struc avoids the overhead of allocating and freeing memory, as well as avoids remembering to free. You have those problems on any solution that uses malloc, calloc, and realloc. On the other hand, wrapping in a struct requires knowing the maximum possible size of the array, and is decidedly wasteful of memory and execution time for large arrays (for example, loading a file into memory and passing the file contents around from function to function by copying).
You can't. You can either pass pointer to array as a parameter and have function modify it, or the function itself can allocate data and return pointer.
in your case
Edit: As caf pointed out one can actually return the
struct
with an array in it, but of course no c-programmer in their right mind would do that.