2D dynamic array (C)

2Darray.c

Dynamic 2D array in C++.

For allocating on continuous memory locations, click here.
Also, bare in mind, about casting malloc.

Before the code, let’s feel what a 2D array is. It is basically a 1D array, where every cell of it, is a pointer to another 1D array. Every cell of the later 1D array, will actually store the real data. See picture below.

2Darray
Here, the left array is the one that holds the pointer and the right ones, are the 1D arrays that hold the data of our program.
We provide code which allocates dynamically an array of N rows and M columns.

/* 
 * File:   main.c
 * Author: SAMARAS
 *
 * Created on 6 January 2013, 8:34 πμ
 */

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

// We return the pointer
int **get(int N, int M) /* Allocate the array */
{
    /* Check if allocation succeeded. (check for NULL pointer) */
    int i, **table;
    table = malloc(N*sizeof(int *));
    for(i = 0 ; i < N ; i++)
        table[i] = malloc( M*sizeof(int) );
    return table;
}

// We don't return the pointer
void getNoReturn(int*** table, int N, int M) {
    /* Check if allocation succeeded. (check for NULL pointer) */
    int i;
    *table = malloc(N*sizeof(int *));
    for(i = 0 ; i < N ; i++)
        *table[i] = malloc( M*sizeof(int) );
}

void fill(int** p, int N, int M) {
    int i, j;
    for(i = 0 ; i < N ; i++)
        for(j = 0 ; j < M ; j++)
            p[i][j] = j;
}

void print(int** p, int N, int M) {
    int i, j;
    for(i = 0 ; i < N ; i++)
        for(j = 0 ; j < M ; j++)
            printf("array[%d][%d] = %d\n", i, j, p[i][j]);
}

void free2Darray(int** p, int N) {
    int i;
    for(i = 0 ; i < N ; i++)
        free(p[i]);
    free(p);
}

int main(void)
{
    int **p;
    //getNoReturn(&p, 2, 5);
    p = get(2, 5);
    fill(p ,2, 5);
    print(p, 2, 5);
    free2Darray(p ,2);
    return 0;
}

This code is developed by me, G. Samaras.

However, there is also another way to malloc a 2D array.

int rows = 10;
int cols = 10;
int *data;
int **array;
int i;
 
/* assume malloc always succeeds */
data = malloc(rows * cols * sizeof(*data));
array = malloc(rows * sizeof(*array));
for (i = 0; i < rows; ++i)
{
    array[i] = &data[i * cols];
}
 
/* Now access array[i][j] and remember to free both data and array when done */

This code comes from Laserlight and was proposed to me by Whiteflags. Both of them top members of C board forum.

Comments from fb group ‘help dit programmers’, done by Orestis(DIT+Columbia), that were made for the code above.

  1. Static 2D arrays are useful for local use, not for passing them to a method. If you want speed and you know that all rows are of same width (let it be w), then the fastest approach is a 1D and replace a[i][j] into a[i*w+j].
  2. The 2nd way is faster, but less flexible. In other words, if the array is of dimensions N*M, then transform it in an 1D. If you know that every row has different, but correlated, width, then use the 2nd way. If nothing is known and you want to increase independently your rows, then use the first one.
  3. The “one size fits all” logic is (in general) suitable, but (in general) slow.
  4. The 2nd way is more flexible. If a function does not know if the array is 1D, it will make it a 2D. If the function is aware of this, then it can optimize and use directly a[i*w+j].
  5. a[i*w+j] requires 1 load. Το a[i][j] requires 2 loads. They impact the performance. On the other hand, multiplications are relatively fast nowadays, pretty much as an addition.

Have questions about this code? Comments? Did you find a bug? Let me know!😀
Page created by G. (George) Samaras (DIT)

8 thoughts on “2D dynamic array (C)

  1. Pingback: Functions, do i have the wrong idea?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s