0

I'm trying to return a 2D array from a function. I've tried some ways mentioned in some websites. But they are helpless. So finally I'd assigned a pointer to the 2D array and returned it from the function. And the sample function's code is given below

float *test(int *x, int *y)
{
    static float res[2][3];
    float[] temp = {1,2,3};
    for(int i=0;i<3;i++) res[0][i] = temp[i];
    for(int i=0;i<3;i++) res[1][i] = temp[i]*-1;
    float *ptr = &res[0][0];
    return ptr;
}

Now I have a problem that how to access this 2D array in main function to print all of it's elements.

Could anyone give a solution? Thanks in advance:)

MOULISHANKAR
  • 111
  • 1
  • 1
  • 6
  • See [this answer](https://stackoverflow.com/a/47235756/841108) – Basile Starynkevitch Apr 16 '21 at 16:05
  • @JohnBollinger yes you are right. I was wrong. my bad – AKL Apr 16 '21 at 17:25
  • 1
    Are you looking to return an object usable as if it were an array with **fixed dimensions**, as in the example code, or at least a fixed second dimension? It makes a difference, and the presence of the unused arguments `x` and `y` leads me to suspect that your example may not be representative of what you are really after. – John Bollinger Apr 16 '21 at 17:43

3 Answers3

0

You could return a pointer to static variable:

char (*modify(char input))[3] 
{
  static char variable[3][3];
  variable[0][0] = input;
  variable[1][1] = input+1;
  return variable;
}

int main() {
    char (*result)[3] = modify(a);
}

However, this is not a reentrant function. Another option is using dynamic memory (i.e. malloc), but memory leaks are quite common when returning pointers to allocated memory.


Another approach it's to pass the array to the function, already allocated, so you don't have to be worried about releasing memory or using statics:

void modify(char variable[][3], char input) {
    variable[0][0] = input;
    variable[1][1] = input+1;
}

int main(void) {
    char result[3][3];
    modify(result,a);
}

A better approach it's to create a typedef to highlight the purpose, length and making easier working with it:

typedef struct { char x[3][3]; } my2D_t;

void modify(my2D_t *variable, char input) {
    variable->x[0][0] = input;
    variable->x[1][1] = input+1;
}
int main() {
    my2D_t result;
    char a = 1;
    modify(&result,a);
}

Also returning by value as tstanisl noticed. It creates another my2D_t, but the compiler will probably end up with something similar to the previous idea for the sake of optimization known as the "as-if" rule:

typedef struct { char x[3][3]; } my2D_t;

my2D_t modify(char input) {
    my2D_t variable;
    variable.x[0][0] = input;
    variable.x[1][1] = input+1;
    
    return variable;
}
int main() {
    char a = 1;
    my2D_t result = modify(a);    
}
Jose
  • 3,306
  • 1
  • 17
  • 22
0

You have to go through dynamic allocation malloc is used for this. Consider this code:

float **result = NULL; // if you want to return 2D array you need double pointer
result = (float **)malloc(2 * sizeof(float *)); // allocating assuming that the allocating will not fail otherwise it return NULL
for(int i = 0; i < 2; i++)
    result[i] = (float *)malloc(3 * sizeof(float));

for(int i = 0; i < 3; i++) result[0][i] = i;
for(int i = 0; i < 3; i++) result[1][i] = i * -1;
return result;

Important part is also in main function where you should deallocate the memory to prevent memory leak. Is's done through free function and you should do this revere to the allocation to free all the memory you allocated.

for(int i=0;i<3;i++) free(result[i]); //done in main
free(result);
Fildo7525
  • 13
  • 4
0

Declare the return type of your function properly, then just return the static array:

float (*test(int *x, int *y))[3]
{
    static float res[2][3];
    float temp[] = {1,2,3};
    for(int i=0;i<3;i++) res[0][i] = temp[i];
    for(int i=0;i<3;i++) res[1][i] = temp[i]*-1;
    return res;
}

Note that returning a static array has the problem that all calls to the function will (re)use that same array, so the second call will clobber the array returned by the first call. You could instead malloc the array:

float (*test(int *x, int *y))[3]
{
    float (*res)[3] = malloc(2 * sizeof *res);
    float temp[] = {1,2,3};
    for(int i=0;i<3;i++) res[0][i] = temp[i];
    for(int i=0;i<3;i++) res[1][i] = temp[i]*-1;
    return res;
}

but then the caller will need to remember to call free on the returned pointer when it is no longer needed.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226