Wednesday, September 1, 2010

Returning Multi-dimensional Arrays from Functions

Returning an array from a function only has meaning if the array was created by the function. Otherwise,
no return is necessary since an existing array is passed by the address. However, if the function has
created the array on the heap, you can return the address of element 0.

The problem here is that you can't use the function return type unless you a) return a type or
b) return a pointer to a type. That is, you cannot return a pointer to an array since an array is not
a type. So, if you create an array of int you can return the array as an int*:

Expand|Select|Wrap|Line Numbers
  1. int* func(int arg)
  2. {
  3.     int* temp = new int[arg];
  4.     return temp;
  5. }
  6. int main()
  7. {
  8.     int* arr = func(5);
  9. }
  10.  
This does not work when you create a multi-dimensional array:
Expand|Select|Wrap|Line Numbers
  1. int (*)[5] func(int arg)   // ERROR: Cannot return an array
  2. {
  3.     int (* temp)[5] = new int[arg][5];
  4.     return temp;
  5. }
  6. int main()
  7. {
  8.     int (* arr)[5] = func(4);
  9. }
  10.  
In this case you could pass in the address of a pointer to an array of 5 int:
Expand|Select|Wrap|Line Numbers
  1. void func(int arg, int (**rval)[5])
  2. {
  3.     int (* temp)[5] = new int[arg][5];
  4.     *rval = temp;
  5. }    
  6. int main()
  7. {
  8.     int (* arr)[5] = 0;
  9.     func(4, &arr);
  10.     //arr is now a [4][5] array of int
  11. }
  12.  
However, if you need to use the function as an RVAL, then you need to return a type. Here the easiest thing to do is define a type to be a pointer to an element of your multi-dimensional array. In this example you would need a pointer to an array of 5 int:

Expand|Select|Wrap|Line Numbers
  1. typedef int (*IntArray5Ptr)[5]; 
Now you have a type that can be returned:

Expand|Select|Wrap|Line Numbers
  1. IntArray5Ptr func(int arg)    
  2.     int (* temp)[5] = new int[arg][5]; 
  3.     return temp; 
  4. }
  5.  
  6. int main() 
  7.     int (* arrA)[5] = func(4); 
You can return a pointer to type in addition to returning a type. So you could define a type to be an element of your array (in the example this is an array of 5 int) and return a pointer to that type:

Expand|Select|Wrap|Line Numbers
  1. typedef int IntArray5[5]; 
  2.  
  3. IntArray5* funcB(int arg) 
  4.     int (* temp)[5] = new int[arg][5]; 
  5.     return temp; 
  6.  
  7.  
  8. int main() 
  9.     int (* arr)[5] = func(4); 
Finally, as was stated at the beginning of this article: There are no multi-dimensional arrays in C++.
Therefore, a function could just create a one-dimensional array of the correct number of elements and return
the address of element 0. In this case, element 0 is a type and you can use the return type of a function
to return a pointer to a type. Then the calling function could typecast the return so the array can be
used with muliple dimensions:

Expand|Select|Wrap|Line Numbers
  1. int* func(int arg)
  2. {
  3.     int * temp = new int[arg];
  4.     return temp;
  5. }    
  6. int main()
  7. {
  8.     //This is arr[60]
  9.     int* arr = func(60);
  10.  
  11.     //This is arr[12][5] --> 12 x 5 = 60
  12.     int (*arr1)[5] = (int(*)[5])func(60);
  13.  
  14.     //This is arr[3][4][5] -> 3 * 4 * 5 = 60
  15.     int (*arr2)[4][5] = (int(*)[4][5])func(60);
  16.  
  17.     //This is arr[1][3][4][5] -> 1*3*4*5 = 60;
  18.     int (*arr3)[3][4][5] = (int(*)[3][4][5])func(60);
  19.  
  20.  
  21.  
  22. }
  23.  

No comments:

Post a Comment