goldenmean
goldenmean

Reputation: 18956

How to pass a 2D dynamically allocated array to a function?

I have a 2 dimensional array dynamically allocated in my C code, in my function main. I need to pass this 2D array to a function. Since the columns and rows of the array are run time variables, I know that one way to pass it is :

-Pass the rows and column variables and the pointer to that [0][0] element of the array

myfunc(&arr[0][0],rows,cols)

then in the called function, access it as a 'flattened out' 1D array like:

ptr[i*cols+j]

But I don't want to do it that way, because that would mean a lot of change in code, since earlier, the 2D array passed to this function was statically allocated with its dimensions known at compile time.

So, how can I pass a 2D array to a function and still be able to use it as a 2D array with 2 indexes like the following?

arr[i][j].

Any help will be appreciated.

Upvotes: 6

Views: 16106

Answers (7)

Arjit
Arjit

Reputation: 565

See the code below. After passing the 2d array base location as a double pointer to myfunc(), you can then access any particular element in the array by index, with s[i][j].

#include <stdio.h>
#include <stdlib.h>

void myfunc(int ** s, int row, int col) 
{
    for(int i=0; i<row; i++) {
        for(int j=0; j<col; j++)
            printf("%d ", s[i][j]);
        printf("\n");
    }
}

int main(void)
{
    int row=10, col=10;
    int ** c = (int**)malloc(sizeof(int*)*row);
    for(int i=0; i<row; i++)
        *(c+i) = (int*)malloc(sizeof(int)*col);
    for(int i=0; i<row; i++)
        for(int j=0; j<col; j++)
            c[i][j]=i*j;
    myfunc(c,row,col);
    for (i=0; i<row; i++) {
        free(c[i]);
    }
    free(c);
    return 0;
}

Upvotes: 6

M.Pak
M.Pak

Reputation: 1

int cols = 4;
    int rows = 3;
    char** charArray = new char*[rows];
    for (int i = 0; i < rows; ++i) {
        charArray[i] = new char[cols];
    }

    // Fill the array
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            charArray[i][j] = 'a';
        }
    }

    // Output the array
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            cout << charArray[i][j];
        }
        cout << endl;
    }

Upvotes: 0

Noah Watkins
Noah Watkins

Reputation: 5546

A 2-d array in C is just an array of arrays. Here ya go:

void with_matrix(int **matrix, int rows, int cols) {
    int some_value = matrix[2][4];
}

int main(int argc, char **argv) {
    int **matrix;
    ... create matrix ...
    with_matrix(matrix, rows, cols);
}

Upvotes: 0

caf
caf

Reputation: 239011

If your compiler supports C99 variable-length-arrays (eg. GCC) then you can declare a function like so:

int foo(int cols, int rows, int a[][cols])
{
    /* ... */
}

You would also use a pointer to a VLA type in the calling code:

int (*a)[cols] = calloc(rows, sizeof *a);
/* ... */
foo(cols, rows, a);

Upvotes: 2

renick
renick

Reputation: 3881

Numerical recipes in C (a book dealing mostly in matrices) suggests a way to do this cleanly and still deal with 2D matrices. Check out the section 1.2 "Matrices and 2D arrays" and the method convert_matrix().

Essentially what you need is to allocate a set of pointers to point to your row vectors. And pass this to your function along with the number of rows and columns.

Upvotes: 0

Axel
Axel

Reputation: 811

As far as I know, all you can pass to a function is a pointer to the first element of an array. When you pass an actual array to a function, it is said that "the array decays into a pointer" so no information about the size(s) of the pointed array remains.

A reference to an object of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T.

I believe you will be able to find more information about this on the C FAQ.

Upvotes: 1

Aaron Digulla
Aaron Digulla

Reputation: 328556

You really can't do this without changing a lot of code. I suggest to wrap this in a structure which contains the limits and then use regexp search'n'replace to fix the accesses.

Maybe use a macro like AA(arr,i,j) (as in Array Access) where arr is the structure.

Upvotes: 1

Related Questions