c - Improvements to dynamically allocate memory for a double pointer to struct inside a pointer to struct -
i wrote code below dynamically allocate memory nested struct: product **product;
purpose of code me learn right or better way dynamically allocate memory using double pointer struct inside pointer struct. code runs fine.
question: corrections or improvements code? in advance sharing experiences.
typedef struct { int price; } product; typedef struct { product **product; int id; } inventory; int main() { int i, j, k, count=0; int n1=2, n2=3, n3=2; inventory *inventory = malloc(n1 * sizeof *inventory); (i=0; i<n1; i++) { inventory[i].product = malloc(n2 * sizeof *inventory[i].product); (j=0; j<n2; j++) { inventory[i].product[j] = malloc(n3 * sizeof *inventory[i].product[j]); } } (i=0; i<n1; i++) { (j=0; j<n2; j++) { (k=0; k<n3; k++) { inventory[i].product[j][k].price = count++; printf("%d " , inventory[i].product[j][k].price); } } } return 0; } output: 0 1 2 3 4 5 6 7 8 9 10 11
the problem product
pointer pointer, if intended array of product
under inventory
, must use ->
notation instead of .
notation price
. (see example 1 below) if however, intended nest array of struct product
under each pointer-to-product
allocate (i.e. subproducts
), see example 2:
note: after each allocation, must check return malloc
insure allocation succeeded. (omitted in example 1 below brevity, shown in full in example 2)
example 1
#include <stdio.h> #include <stdlib.h> typedef struct { int price; } product; typedef struct { product **product; int id; } inventory; int main () { int i, j; int n1 = 2, n2 = 3; /* allocated / initiaize inventory , product */ inventory *inventory = malloc (n1 * sizeof *inventory); (i = 0; < n1; i++) { inventory[i].id = i; inventory[i].product = malloc (n2 * sizeof *inventory[i].product); (j = 0; j < n2; j++) { inventory[i].product[j] = malloc (sizeof *inventory[i].product[j]); inventory[i].product[j]->price = (j + 1) * 2; } } /* print inventory / procduct price */ (i = 0; < n1; i++) { printf ("\n product id : %d\n", inventory[i].id); (j = 0; j < n2; j++) { printf (" price : %d\n", inventory[i].product[j]->price); } } /* free memory */ (i = 0; < n1; i++) { (j = 0; j < n2; j++) free (inventory[i].product[j]); free (inventory[i].product); } free (inventory); return 0; }
output
$ ./bin/allocate_ptr_in_struct product id : 0 price : 2 price : 4 price : 6 product id : 1 price : 2 price : 4 price : 6
memory use error check
$ valgrind ./bin/allocate_ptr_in_struct ==10167== memcheck, memory error detector ==10167== copyright (c) 2002-2012, , gnu gpl'd, julian seward et al. ==10167== using valgrind-3.8.1 , libvex; rerun -h copyright info ==10167== command: ./bin/allocate_ptr_in_struct ==10167== product id : 0 price : 2 price : 4 price : 6 product id : 1 price : 2 price : 4 price : 6 ==10167== ==10167== heap summary: ==10167== in use @ exit: 0 bytes in 0 blocks ==10167== total heap usage: 9 allocs, 9 frees, 104 bytes allocated ==10167== ==10167== heap blocks freed -- no leaks possible ==10167== ==10167== counts of detected , suppressed errors, rerun with: -v ==10167== error summary: 0 errors 0 contexts (suppressed: 2 2)
allocation of nested subproduct
example 2
per comment intended allocate nested struct under **product
change straightforward:
#include <stdio.h> #include <stdlib.h> typedef struct { int price; } product; typedef struct { product **product; int id; } inventory; int main () { int i, j, k; int n1 = 2, n2 = 3, n3 = 2; /* allocated / initiaize inventory , product */ inventory *inventory = malloc (n1 * sizeof *inventory); if (!inventory) { fprintf (stderr, "error: virtual memory exhausted.\n"); exit (exit_failure); } (i = 0; < n1; i++) { inventory[i].id = i; if (!(inventory[i].product = malloc (n2 * sizeof *inventory[i].product))) { fprintf (stderr, "error: virtual memory exhausted.\n"); exit (exit_failure); } (j = 0; j < n2; j++) { if (!(inventory[i].product[j] = malloc (n3 * sizeof *inventory[i].product[j]))) { fprintf (stderr, "error: virtual memory exhausted.\n"); exit (exit_failure); } (k = 0; k < n3; k++) inventory[i].product[j][k].price = (j + 1) * 2 * (k + 1); } } /* print inventory / procduct price */ (i = 0; < n1; i++) { printf ("\n inventory id : %d\n", inventory[i].id); (j = 0; j < n2; j++) { printf ("\n product[%d]\n", j); (k = 0; k < n3; k++) printf (" subproduct[%d][%d] price : %d\n", j, k, inventory[i].product[j][k].price); } } /* free memory */ (i = 0; < n1; i++) { (j = 0; j < n2; j++) free (inventory[i].product[j]); free (inventory[i].product); } free (inventory); return 0; }
output
$ ./bin/allocate_ptr_in_struct inventory id : 0 product[0] subproduct[0][0] price : 2 subproduct[0][1] price : 4 product[1] subproduct[1][0] price : 4 subproduct[1][1] price : 8 product[2] subproduct[2][0] price : 6 subproduct[2][1] price : 12 inventory id : 1 product[0] subproduct[0][0] price : 2 subproduct[0][1] price : 4 product[1] subproduct[1][0] price : 4 subproduct[1][1] price : 8 product[2] subproduct[2][0] price : 6 subproduct[2][1] price : 12
memory use error check
$ valgrind ./bin/allocate_ptr_in_struct ==23024== memcheck, memory error detector ==23024== copyright (c) 2002-2012, , gnu gpl'd, julian seward et al. ==23024== using valgrind-3.8.1 , libvex; rerun -h copyright info ==23024== command: ./bin/allocate_ptr_in_struct ==23024== inventory id : 0 product[0] subproduct[0][0] price : 2 subproduct[0][1] price : 4 product[1] subproduct[1][0] price : 4 subproduct[1][1] price : 8 product[2] subproduct[2][0] price : 6 subproduct[2][1] price : 12 inventory id : 1 product[0] subproduct[0][0] price : 2 subproduct[0][1] price : 4 product[1] subproduct[1][0] price : 4 subproduct[1][1] price : 8 product[2] subproduct[2][0] price : 6 subproduct[2][1] price : 12 ==23024== ==23024== heap summary: ==23024== in use @ exit: 0 bytes in 0 blocks ==23024== total heap usage: 9 allocs, 9 frees, 128 bytes allocated ==23024== ==23024== heap blocks freed -- no leaks possible ==23024== ==23024== counts of detected , suppressed errors, rerun with: -v ==23024== error summary: 0 errors 0 contexts (suppressed: 2 2)
Comments
Post a Comment