Archive

Posts Tagged ‘malloc’

Dinamically allocate memory for a bi-dimensional array in C

January 7, 2014 No comments

One of the biggest faults of an array is that we have to define it’s size in coding time. Sometimes it’s the easiest thing to do and it’s ok, we may waste some bytes (As in a little string when we create a 100 bytes array); sometimes we choose the right size (for example when creating an array with the names of the months). But many times we have no idea what the size it must have, if it is very small we probably will fail short and if it is very large, we will wast a lot of memory.

But one of the tools C has is the dinamic memory allocation (malloc function and derivates), but it can allocate memory for an structure, or an unidimensional array, if we want to allocate memory for a two-dimensional, three-dimensional array or so, we must allocate memory for each of the arrays composing the multi-dimensional array,

To have a dynamic array, we must have a double pointer, so it can be declared as:

1
int **myArray;

To allocate memory for that variable, first we must allocate all rows, and then, inside each row, we must allocate the columns. For example for a 3×3 array, we must:

  • Allocate 3 rows
  • Allocate 3 columns for 1st row
  • Allocate 3 columns for 2nd row
  • Allocate 3 columns for 3rd row

The next example is using calloc() function to allocate memory (we can do it with malloc with no difficulties:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdlib.h>
#include <stdio.h>

void** calloc2d (int rows, int cols, int elemSize)
{
  void **variable;
  int i;

  variable=(void**)calloc(rows, sizeof(void*));
 
  for (i=0; i<rows; i++)
    {
      variable[i]=calloc(cols, elemSize);
    }
  return variable;
}

void free2d (void **var, int rows)
{
  int i;
  for (i=0; i<rows; i++)
    free(var[i]);

  free(var);
}

void randomValues(int **v, int rows, int cols)
{
  int i,j;
  for (i=0; i<rows; i++)
    for (j=0; j<cols; j++)
      v[i][j]=rand();
}

int main(int argc, char *argv[])
{
  int rows=10000;
  int cols=20000;
  getchar();
  int ** v=(int**)calloc2d(rows, cols, sizeof(int));

  randomValues(v, rows, cols);
  getchar();

  free2d((void**)v, rows);
  getchar();
  return EXIT_SUCCESS;
}

The first function (calloc2d()) will allocate dinamically bi-dimensional arrays indicating rows and columns, free2d() will free memory allocated only indicating rows.
The function randomValues() assign random integer values to the array, to use the allocated memory, so the memory will be really used.

The program does three pauses, one before anything (press enter, to continue), another one when the memory is allocated, and the other one when everything in freed. We can use a memory analysis program, or even top to see what’s going on.

Be careful if your system is low on memory, because 10000 rows * 20000 columns * 4 (sizeof(int)) = 800000000 = 8*10^8 or 800Mb

Photo cibomahto (Flickr) CC-by

Top