Search code examples
arraysccompiler-warnings

warning: returning ‘float (*)[3]’ from a function with incompatible return type ‘float *’


I am getting the error 'warning: returning ‘float (*)[3]’ from a function with incompatible return type ‘float *’' when I'm trying to return an array in a function. I've read C has problems with returning arrays but don't really understand why and what to do to fix it. This is my code:

float * buildlocs(int L, int W, int H){
int c = 0, xmin, xmax, x, ymin, ymax, y, h;
unsigned int nX, nY;
L = L/4;
W = W/4;
float cellarray[16][3];


for(nX = 0; nX < 4;nX++) {
    for(nY = 0; nY < 4;nY++) {
        xmin = 0+L*(nX-1);
        xmax = L*nX;
        x = xmin+rand()*(xmax-xmin);
        
        ymin = 0+W*(nY-1);
        ymax = W*nY;
        y = ymin+rand()*(ymax-ymin);
        
        h = rand()*H;

        for(int i = 0; i < 3; i++){
            if(i == 0){
                cellarray[c][i] = x;                     
            }
            if(i == 1){
                cellarray[c][i] = y;  
            }
            if(i == 2){
                cellarray[c][i] = h;
            }

        }

        c = c + 1;
    }
}

return cellarray;
}

The goal is to have an 2d array with 16 entries which contain 3 variables. Could someone please help me fix the error?


Solution

  • There are two problems:

    First, a float[16][3] is not a float*. Second, float cellArray[16][3] ceases to exist at the end of the function - it is a local variable that only exists in that function. when you return the address of the array, the pointer will point to something non existing - a so-called dangling pointer.

    To solve the issue, you need to allocate the array either dynamically and return the pointer to the dynamically allocated array like this (dont forget to free when you are done with cellArray):

    float* cellArray = malloc(sizeof(float)*16*3); // this is one contiguous block of floats, you have to figure out how you want to index into this block, since it's stricly speaking not a two dimensional array.
    //...//
    return cellArray;
    

    OR, what i find more elegant is, passing a pointer to an already existing array:

    void buildlocs(float* outLocs, int L, int W, int H); // added parameter to take a float*
    
    //in your function that calls buildlocs:
    
    float[16][3] cellArray;
    buildlocs(&cellArray[0],L,W,H); // pass allocated array into function, again, this is a pointer, not a two-dimensional array