Thursday, November 28, 2013

How to return a two-dimentional array from a function in C

In most of the cases, there is no need of returning arrry from a function. In C, passing array by its name, the address of its first element is passed and any changes made on its formal arguments reflects on actual arguments. But sometimes, there is situation where an array have to be returned from a function.

There are two approaches, one is through a struct, another one is through pointer. The first approach is much simpler and easier to understand, it can also eliminate many pitfalls. But it is not ideal for every scenario. You would avoid using a struct by value when the size of the struct is not constant or very large.

Struct approach:

struct t_thing {
    int a[3][3];
};

struct t_thing retArr() {
    struct t_thing thing = {
        {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        }
    };

    return thing;
}

int main(int argc, const char* argv[]) {
    struct t_thing thing = retArr();
    ...
    return 0;
}


This approach is pretty straight forward and easy to understand.

Pointer approach:
You might think it is as easy as this:
int** retArr()
{
    int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
    return a;
}

int main()
{
    int a[3][3] = retArr();
    return 0;
}

The problem with the above problem is that "a[3][3]" declared in retArr() is a local variable, the memory will be released after the function returns. So a became a dangling pinter.

The correct way of returning a multidimentional array from a function is below:

char **allocate_matrix(int row, int column) {

    char **matrix = (char **)malloc(row * sizeof(char *));
    int i;

    for(i = 0; i<row; i++)
        matrix[i] = (char *)malloc(column * sizeof(char));

    /* array oppration */

    return matrix;

}

int main(int argc, char *argv[]) {
    char** matrix;

    matrix = allocate_matrix(row, column)

    ...
}

No comments: