How does a function in C language return a two-dimensional array and obtain the size of the returned two-dimensional array

  c++, question
public int[][] getInfo() {
 int[][] result = new int[10][20];
 return result;
 }
 public void main() {
 int[][] result = getInfo();
 System.out.println ("result length:"+result.length ");
 for (int i = 0;   i < result.length;  i++) {
 for (int j = 0;   j < result.length;  j++) {
 System.out.println(result[i][j]);
 }
 }
 }

The above is a piece of java code, the function is to obtain the returned two-dimensional array, and output the size of the two-dimensional array, and traverse the contents of the array, provided that I do not know the size of the returned array.
How to translate it into C language? In fact, I just want to understand how C language returns a two-dimensional array and how to obtain the size of the array.

For example, use some black magic (black magic in C language is, of course, macro+pointer). Some people have proposed to write down the length of an array before the first address.

#include <stdio.h>
 #include <stdlib.h>
 
 typedef struct array_meta_t {
 int length;
 int elem_size;
 } array_meta;
 
 #define TO_META(array) (((array_meta*)array) - 1)
 #define TO_ARRAY(meta) ((void*)(meta + 1))
 
 void* array_allocate(int length, int type_size)
 {
 array_meta* new_array = malloc(length * type_size + sizeof(array_meta));
 new_array->length = length;
 new_array->elem_size = type_size;
 
 return TO_ARRAY(new_array);
 }
 
 #define array_length(array) (TO_META(array)->length)
 #define array_type_size(array) (TO_META(array)->elem_size)
 #define array_create(type, length) ((type*)array_allocate(length, sizeof(type)))
 #define array_release(array) (free(TO_META(array)))
 
 int** return_some_array()
 {
 int** my_array = array_create(int*, 10);
 
 int value = 0;
 
 for(int i = 0;   i < array_length(my_array);  i++)
 my_array[i] = array_create(int, 20);
 
 return my_array;
 }
 
 int main()
 {
 int** result = return_some_array();
 printf("The array has size %dx%d\n",
 array_length(result),
 array_length(*result));
 // Output: The array has size 10x20
 
 for(int i = 0;   i < array_length(result);  i++)
 array_release(result[i]);
 array_release(result);
 }

This method has three advantages over returning a structure pointer:

  • Meta-information structures are hidden from users (a bit like private fields in object-oriented), where array_length is a macro so it can be written and rewritten as a function is read-only

  • You can use traditional[]The operator takes the offset directly and does not need to dereference or the like first.

  • Another is that if a structure is returned, it is equivalent to dynamic allocation twice, which makes memory management more troublesome. All that is needed here ismallocOnce, then release once.

In C++, you don’t need to bother to use vector. You can use two template elements to reload arrays of different lengths and get them done. Remember that parameters are references:

template<int M, int N>
 void print_length(int (&) [M][N]) {
 cout << M << ' ' << N << endl;
 }
 //  ...
 int arr[5][6];
 print_length(arr);  // Output: 5 6