I'm sorry you are having difficulty with your 2D allocation, it really isn't too difficult. To dynamically allocate and access your elements with array[x][y]
notation, you need to allocate x
pointers to an array of float
's (your rows), then allocate an y
arrays of float
's (your elements/columns) for each row. (no different than allocating an array of pointers to strings to hold lines of text)
An example of a simple allocation/initialization function with calloc
(with m
rows and n
columns) shown without error checking on allocation is:
float **mtrx_calloc (size_t m, size_t n)
{
register size_t i;
float **array = calloc (m, sizeof *array);
for (i = 0; i < m; i++)
{
array [i] = calloc (n, sizeof **array);
}
return array;
}
To allocate a 3x4
matrix, you would use it like this:
float **matrix = mtrx_calloc (3, 4);
You can then manipulate the matrix as you like accessing all elements with matrix[x][y]
notation. Also note the use of size_t
instead of int
. Your rows
and columns
and iterator
will never be negative, so choosing size_t
or unsigned
type makes more sense.
Sometimes rather than looking at pieces of code, it is good to have a working example. I put together a short working example to help you along that includes all points we have discussed so far in the comments and above. It includes error checking on memory allocation omitted above. If you have any questions, just drop a comment.
#include <stdio.h>
#include <stdlib.h>
float **mtrx_calloc (size_t m, size_t n); /* initialize elements to 0 */
void mtrx_prn (size_t m, size_t n, float **matrix); /* print matrix with/pad */
void mtrx_free (size_t m, float **matrix); /* free memory allocated */
int main (void)
{
/* allocate the 3x4 matrix */
float **matrix = mtrx_calloc (3, 4);
/* fill with misc values */
register size_t i = 0, j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
matrix [i][j] = (float)(i + j);
}
/* print matrix */
printf ("\nThe dynamically allocated 3x4 matrix is:\n\n");
mtrx_prn (3, 4, matrix);
/* free memory alocated */
mtrx_free (3, matrix);
/* just to make it look pretty */
printf ("\n");
return 0;
}
/* allocate/initialize mxn matrix */
float **mtrx_calloc (size_t m, size_t n)
{
register size_t i;
float **array = calloc (m, sizeof *array);
if (!array) { /* validate allocation */
fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
exit (EXIT_FAILURE);
}
for (i = 0; i < m; i++)
{
array[i] = calloc (n, sizeof **array);
if (!array[i]) { /* validate allocation */
fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
exit (EXIT_FAILURE);
}
}
return array;
}
/* print a (m x n) matrix (check pad alloc) */
void mtrx_prn (size_t m, size_t n, float **matrix)
{
register size_t i, j;
for (i = 0; i < m; i++)
{
char *pad = "[ ";
for (j = 0; j < n; j++)
{
printf ("%s%6.3f", pad, matrix [i][j]);
pad = ", ";
}
printf ("%s", " ]\n");
}
}
void mtrx_free (size_t m, float **matrix)
{
register size_t i;
for (i = 0; i < m; i++)
{
free (matrix [i]);
}
free (matrix);
}
Output
(note: the fill with misc values equation was changed to prevent overflow on entry of large m x n
, so output values will differ from below)
$ ./bin/mtrx_dyn_example
The dynamically allocated 3x4 matrix is:
[ 1.900, 2.800, 3.700, 4.600 ]
[ 2.800, 3.700, 4.600, 5.500 ]
[ 3.700, 4.600, 5.500, 6.400 ]
Leak Check with valgrind
When you are creating/allocating blocks of memory dynamically, you are responsible to tracking what you have allocated, preserving the starting address for the block of memory, and freeing the block of memory when you no longer need it. A great tool to help you check your memory use is a memory checker such as valgrind
. (similar tools are available for all platforms). Simple to use, just valgrind ./progname
. It will confirm for you whether any blocks remain unfreed and whether there are any access errors regarding your allocated blocks:
$ valgrind ./bin/mtrx_dyn_example
==15800== Memcheck, a memory error detector
==15800== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==15800== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==15800== Command: ./bin/mtrx_dyn_example
==15800==
The dynamically allocated 3x4 matrix is:
[ 1.900, 2.800, 3.700, 4.600 ]
[ 2.800, 3.700, 4.600, 5.500 ]
[ 3.700, 4.600, 5.500, 6.400 ]
==15800==
==15800== HEAP SUMMARY:
==15800== in use at exit: 0 bytes in 0 blocks
==15800== total heap usage: 4 allocs, 4 frees, 72 bytes allocated
==15800==
==15800== All heap blocks were freed -- no leaks are possible
==15800==
==15800== For counts of detected and suppressed errors, rerun with: -v
==15800== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)