2

reading a few articles on dynamic memory allocation for multidimensional arrays in c, I came across the following code snippet: (article link)

#define COLS 5

int (*rptr)[COLS];

    int main(void)
        {
            int nrows = 10;
            int row, col;
            rptr = malloc(nrows * COLS * sizeof(int));
            for (row = 0; row < nrows; row++)
              for (col = 0; col < COLS; col++)
                    rptr[row][col] = 17;
            return 0;
        }

Here, a multidimensinal array is defined as int (*rptr)[COLS] and then dynamically linked to malloc(nrows * COLS * sizeof(int)).

Now the question is that how does the pointing work, eg: if the pointing address start from 100,101,102...etc

(assuming int takes 1 byte for simplicity)

rptr[0] points to ->  100 
rptr[1] points to ->  105 

Does the compiler internally link the address accordingly based on the column size as soon as malloc(nrows * COLS * sizeof(int)) is executed?

Thanks

2
  • 1
    If you have a modern C compiler (C99 will do) you can do the allocation much simpler, namely int (*rptr)[nrows] = malloc(sizeof(int[nrows][ncols])); where nrows and ncols can be variables. Commented Jan 4, 2012 at 11:40
  • I think the question is nearly identical to stackoverflow.com/questions/917783/… (How do I work with dynamic multi-dimensional arrays in C?) Commented Jan 4, 2012 at 11:50

1 Answer 1

4

Consider this ordinary array allocation:

int* a = malloc(sizeof(int) * 10);

The type "int*" is of course a pointer to an int, and sizeof(*a) == sizeof(int). When we do a[3], this is converted to:

*(a + 3)

which (assuming sizeof(long)==sizeof(void*)) dereferences the address:

(long)a + 3*sizeof(*a) == (long)a + 3*sizeof(int)

The way to think about your sample code is that the type "int (*rptr)[COLS]" is a pointer to a (static, one dimensional) int array of size COLS. In other words, sizeof(*rptr) == COLS * sizeof(int). However, just as with the "int *", we can allocate an array of these fixed-size one-dimensional array objects. The indexing "rptr[row]" gets converted to:

*(rptr + row)

which dereferences the address:

(long)rptr + row*sizeof(*rptr) == (long)rptr + row*COLS*sizeof(int)

The resulting type is "int [COLS]", so it can be indexed into again by "[col]". The address calculation ends up being precisely what you want:

(long)rptr + row*COLS*sizeof(int) + col*sizeof(int)

This solution is mentioned at http://c-faq.com/aryptr/dynmuldimary.html, and only works if the number of columns (or in general, all but the first dimension) is fixed at compile time. The syntax gets a bit messy as the number of dimensions increases. If you need more than one dimension to be determined dynamically at runtime, see that page for other strategies.

Sign up to request clarification or add additional context in comments.

1 Comment

No it also works for a dynamic number of columns if you have a modern C compiler that implements C99.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.