C allocating 2-dimensional integer array -


how use realloc , malloc declare global variable 2-dimensional integer array int array[][] reallocate once numbers x , y given int array[x][y]?

there several points consider when simulating 2d array or matrix in c. first understanding allocating. simulate 2d array access array[m][n], doing first allocating array of m pointers pointer int. provides m int* (or rows) have available allocate n int (columns).

so put, allocate m pointers int* rows , n int columns.

now before @ code, there practical choice make on whether use malloc allocate memory (columns specifically) or whether use calloc. why? before can attempt access element of array, must initialize element hold value. otherwise, attempt read element, attempt read uninitialized value undefined behavior , can send program spinning off land of no return..

why calloc instead of malloc. not calloc allocate space you, initializes/sets memory @ location 0/null (0 in case of numeric type, null in case of pointer -- both 0) prevents inadvertent read uninitialized element because elements initialized 0 begin with. free set loop , set every value 0 (or whatever) way, overlooked new c programmers. calloc can protect against yourself. let's @ allocation function:

/* allocate/initialize mxn matrix */ int **mtrx_calloc (size_t m, size_t n) {     register size_t i;     int **array = calloc (m, sizeof *array);      if (!array) {   /* validate allocation  */         fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);         exit (exit_failure);     }      (i = 0; < 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; } 

the allocation function straight forward. accepts m , n arguments (type size_t -- indexes cannot negative), , returns allocated, initialized set of m pointers arrays of n int. let's @ use allocate my_array 4x5 matrix of int:

int **my_array = mtrx_calloc (4, 5); 

throughout remainder of code, can access element my_array[0-3][0-4] (indexes 0 based, rest of indexing in c)

what realloc? when talking fixed size arrays, time need reallocate memory if need resize array. (now granted create new array , copy old/new) however, since reallocating memory important concept in c, lets write function reallocate number of rows our matrix.

let's find need my_array 8x5 matrix instead of 4x5 matrix. in case need realloc number of pointers int* allow addition of 4 more rows. need allocated space hold new values rows 5-8 (indexes 4-7).

you need keep track number of rows have allocated, if send pointer current number of rows, can update value @ address , have value available in our calling function (main() in case). thing need preserve in main before make call reallocate old value m (to allow filling new space values, etc.) our reallocation of rows following:

/* realloc array of pointers int* setting memory 0. */ int **realloc_rows (int **ap, size_t *m, size_t n, size_t newm) {     if (newm <= *m) return ap;     size_t = 0;     int **tmp = realloc (ap, newm * sizeof *ap);     if (!tmp) {         fprintf (stderr, "%s() error: memory reallocation failure.\n", __func__);         // return null;         exit (exit_failure);     }     ap = tmp;      (i = *m; < newm; i++)     {         ap[i] = calloc (n, sizeof **ap);          if (!ap[i]) {   /* validate allocation  */             fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);             exit (exit_failure);         }     }     *m = newm;      return ap; } 

now important notice, not directly assign newly reallocated value our array variable, instead tmp variable. why? if reallocation fails, realloc frees newly allocated space returns null, cause complete loss of our data if had assigned return of realloc our array. using tmp array instead, have flexibility handle failure required. sample call reallocate 4 additional rows like:

my_array = realloc_rows (my_array, &m, n, m + 4); 

that's longer overview of 2d matrix/array intended, there lot of considerations go simple set of functions handle dynamically allocating , reallocating simulated 2d array. that, leave example at. example create 3x4 2d array default, can specify size arguments program. example:

./programname 4 5 

will create initial 4x5 2d array, instead of default. show use of realloc, whatever size allocated resized add 4 rows , fill new rows miscellaneous values. both original size , reallocated size arrays printed stdout. let me know if have questions:

/*     gcc -wall -wextra -o progname progname.c */  #include <stdio.h> #include <stdlib.h>  int **mtrx_calloc (size_t m, size_t n);                /* initialize elements 0  */ int **realloc_rows (int **ap, size_t *m, size_t n, size_t newm); /* resize newm x n */ void mtrx_prn (size_t m, size_t n, int **matrix);      /* print matrix with/pad     */ void mtrx_free (size_t m, int **matrix);               /* free memory allocated     */  int main (int argc, char **argv) {     /* set initial size arguments given (default: 3 x 4) */     size_t m = argc > 2 ? (size_t)atoi (argv[1]) : 3;     size_t n = argc > 2 ? (size_t)atoi (argv[2]) : 4;      /* allocate m x n matrix */     int **matrix = mtrx_calloc (m, n);      /* fill misc values */     register size_t = 0, j = 0;     (i = 0; < m; i++)     {         (j = 0; j < n; j++)             matrix [i][j] = (int)(i + j);     }      /* print matrix */     printf ("\nthe dynamically allocated %zux%zu matrix is:\n\n", m, n);     mtrx_prn (m, n, matrix);      /* reallocate matrix - add 4 rows */     printf ("\nreallocate matrix %zux%zu:\n\n", m + 4, n);     size_t oldm = m;     matrix = realloc_rows (matrix, &m, n, m + 4);      /* fill new rows misc values */     (i = oldm; < m; i++)     {         (j = 0; j < n; j++)             matrix [i][j] = (int)(i + j);     }      mtrx_prn (m, n, matrix);      /* free memory alocated */     mtrx_free (m, matrix);      /* make pretty */     printf ("\n");      return 0; }  /* allocate/initialize mxn matrix */ int **mtrx_calloc (size_t m, size_t n) {     register size_t i;     int **array = calloc (m, sizeof *array);      if (!array) {   /* validate allocation  */         fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);         exit (exit_failure);     }      (i = 0; < 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; }  /* realloc array of pointers int* setting memory 0. */ int **realloc_rows (int **ap, size_t *m, size_t n, size_t newm) {     if (newm <= *m) return ap;     size_t = 0;     int **tmp = realloc (ap, newm * sizeof *ap);     if (!tmp) {         fprintf (stderr, "%s() error: memory reallocation failure.\n", __func__);         // return null;         exit (exit_failure);     }     ap = tmp;      (i = *m; < newm; i++)     {         ap[i] = calloc (n, sizeof **ap);          if (!ap[i]) {   /* validate allocation  */             fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);             exit (exit_failure);         }     }     *m = newm;      return ap; }  /* print (m x n) matrix (check pad alloc) */ void mtrx_prn (size_t m, size_t n, int **matrix) {     register size_t i, j;      (i = 0; < m; i++)     {         char *format = "[ %2d";         (j = 0; j < n; j++)         {             printf (format, matrix [i][j]);             format = ", %2d";         }         puts(" ]");     } }  void mtrx_free (size_t m, int **matrix) {     register size_t i;      (i = 0; < m; i++)     {         free (matrix [i]);     }     free (matrix); } 

create 4x5 matrix , reallocate 8x5

$ ./bin/mtrx_dyn_int 4 5  dynamically allocated 4x5 matrix is:  [  0,  1,  2,  3,  4 ] [  1,  2,  3,  4,  5 ] [  2,  3,  4,  5,  6 ] [  3,  4,  5,  6,  7 ]  reallocate matrix 8x5:  [  0,  1,  2,  3,  4 ] [  1,  2,  3,  4,  5 ] [  2,  3,  4,  5,  6 ] [  3,  4,  5,  6,  7 ] [  4,  5,  6,  7,  8 ] [  5,  6,  7,  8,  9 ] [  6,  7,  8,  9, 10 ] [  7,  8,  9, 10, 11 ] 

check memory errors/leaks

$ valgrind ./bin/mtrx_dyn_int 4 5 ==31604== memcheck, memory error detector ==31604== copyright (c) 2002-2012, , gnu gpl'd, julian seward et al. ==31604== using valgrind-3.8.1 , libvex; rerun -h copyright info ==31604== command: ./bin/mtrx_dyn_int 4 5 ==31604==  dynamically allocated 4x5 matrix is:  [  0,  1,  2,  3,  4 ] [  1,  2,  3,  4,  5 ] [  2,  3,  4,  5,  6 ] [  3,  4,  5,  6,  7 ]  reallocate matrix 8x5:  [  0,  1,  2,  3,  4 ] [  1,  2,  3,  4,  5 ] [  2,  3,  4,  5,  6 ] [  3,  4,  5,  6,  7 ] [  4,  5,  6,  7,  8 ] [  5,  6,  7,  8,  9 ] [  6,  7,  8,  9, 10 ] [  7,  8,  9, 10, 11 ]  ==31604== ==31604== heap summary: ==31604==     in use @ exit: 0 bytes in 0 blocks ==31604==   total heap usage: 10 allocs, 10 frees, 256 bytes allocated ==31604== ==31604== heap blocks freed -- no leaks possible ==31604== ==31604== counts of detected , suppressed errors, rerun with: -v ==31604== error summary: 0 errors 0 contexts (suppressed: 2 2) 

Comments

Popular posts from this blog

python - Mongodb How to add addtional information when aggregating? -

java - Spring Data JPA: Why findOne(id) executing delete query internally? -

java - Incorrect order of records in M-M relationship in hibernate -