0

EDIT after a sleeping night

this code works

#include <stdlib.h>

#define MAX_X   5
#define MAX_Y   6

void main ( void ){
    int     i,j,k;
    double *aux;
    double  *MM[MAX_X][MAX_Y];

    // Populate MM
    for (i = 0; i < MAX_X; i++)
        for (j = 0; j < MAX_Y; j++ ){
            aux = calloc (100,sizeof(double));
            if (aux != NULL)
                for (k = 0; k < 100; k++)
                    aux[k] = 10.0 * (i + j + k);
            MM[i][j] = aux;
        }

    // do something
    
    // Free MM
    for (i = 0; i < MAX_X; i++)
        for (j = 0; j < MAX_Y; j++ ){
            if (MM[i][j] != NULL)
                free (MM[i][j]);
        }

}

What I want is :

#include <stdlib.h>


#define MAX_X   5
#define MAX_Y   6

double *[][] calc_MM ( void ){
    double  *MM[MAX_X][MAX_Y];
    
    for (i = 0; i < MAX_X; i++)
        for (j = 0; j < MAX_Y; j++ ){
            aux = calloc (100,sizeof(double));
            if (aux != NULL)
                for (k = 0; k < 100; k++)
                    aux[k] = 10.0 * (i + j + k);
            MM[i][j] = aux;
        }
    return MM;
}

void free_MM ( double *MM[MAX_X][MAX_Y] ){
    int     i,j;
    
    for (i = 0; i < MAX_X; i++)
        for (j = 0; j < MAX_Y; j++ ){
            if (MM[i][j] != NULL)
                free (MM[i][j]);
        }
}

void main ( void ){
    int     i,j,k;
    double *aux;
    double  *MM[MAX_X][MAX_Y];


    // Populate MM
    MM = calc_MM ();
    
    // do something
    
    // Free MM
    free_MM ( MM );
}

what type should I define so I can pass MM and return it from a function? double *MM[MAX_X][MAX_Y];

OLD question I have a code that works fine

double *foo (int i, int j){
    double *aux;

    do something
    return aux;
} 

void main (void){
    double  *MM[MAX_X][MAX_Y];
..
..
    // Calc as MM
    for (i = 0; i < MAX_X; i++)
        for (j = 0; j < MAX_Y; j++ )
            MM[i][j] = foo (i,j);
}

and I would like to put the loop inside a function.

double *foo (int i, int j){
    double *aux;

    do something
    return aux;
} 

double ***calc_MM ( some input ) {
    int i,j;
    double ***MM;

    for (i = 0; i < MAX_X; i++)
        for (j = 0; j < MAX_Y; j++ )
            MM[i][j] = foo (i,j);

    return MM;
}

void main (void){
    double  *MM[MAX_X][MAX_Y];
..
..
    // Calc as MM
    MM = calc_MM ( some input )
}

MAX_X and MAX_Y are #define constant and later will be read from envp

Sorry if I am not clear, but I have to use MM and it would become much more modular if I could pass and return it from a function.

I need some help in how I can define double *MM[MAX_X][MAX_Y]; so I pass and return it from a function.

I tried some combination of * and const *, etc but I always have a compiler error.

Returning `double * (*)[35]` from a function with incompatible return type `double ** const*` [-Werror=incompatible-pointer-types].

I think this one may answer my question but I did not understand Designating a pointer to a 2D array

aoliv
  • 11
  • 2
  • 3
    Do you want a 2D array, a 2D array of pointers, or a pointer to a 2D array? – tadman Feb 21 '23 at 19:46
  • 1
    Questions seeking debugging help should generally provide a [mre] of the problem, which includes a function `main` and all `#include` directives. This allows other people to easily test your program, by simply using copy&paste. Therefore, please show us your code which produces the error. – Andreas Wenzel Feb 21 '23 at 19:50

3 Answers3

0

For starters according to the C Standard the function main without parameters shall be declared like

int main( void )
{
    double  *MM[MAX_X][MAX_Y];
    ..
    ..
    // Calc as MM
    MM = calc_MM ( some input )
}

where the function calc_MM is called like

calc_MM ( MM )

then in any case this statement

    MM = calc_MM ( some input )

is invalid because arrays do not have the assignment operator.

Nevertheless in you want to return a pointer to the first element of the passed array then the function declaration will look like

double * ( * calc_MM( double  *MM[MAX_X][MAX_Y] ) )[MAXY]; 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

function to return a pointer to a 2D array

foo() returns a pointer to a 2-D array. Yet what OP asks for may not meets the other coding objectives.

#define MAX_X 3
#define MAX_Y 5

double (*foo(void))[MAX_X][MAX_Y] {
  static double a[MAX_X][MAX_Y];
  return &a;
}

@0___________ commented "it cant return another distinct one on the next call". Easy enough to offer a function that does.

#include <stdlib.h>

double (*foo(void))[MAX_X][MAX_Y] {
  double (*a)[MAX_X][MAX_Y] = malloc(sizeof *a);
  return a;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0
  1. If sizes are known compile time:
#define MAX_ROW 5 
#define MAX_COL 6

double (*compileTimeConst(void))[MAX_ROW][MAX_COL]
{
    return malloc(sizeof(double[MAX_ROW][MAX_COL]));
}
  1. sizes are not known compile time (VLAs): Unfortunately, only void pointer can be used as the return value, or you can pass pointer to pointer to array
void *VLA(size_t MAX_ROW, size_t MAX_COL, double (**array)[MAX_COL])
{
    double (*m)[MAX_COL] = malloc(MAX_ROW * sizeof(**array));
    if(array) *array = m;
    return m;
}

void caller(size_t MAX_ROW, size_t MAX_COL)
{
    double (*array)[MAX_COL] = VLA(100, 200, NULL);
    double (*array1)[MAX_COL];

    VLA(100, 200, &array1);

    free(array);
    free(array1);
}
0___________
  • 60,014
  • 4
  • 34
  • 74