Advertisement
B1KMusic

The many ways of doing arrays in C.

Oct 6th, 2015
322
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.07 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define W 5
  5. #define H 5
  6.  
  7. #define REND_2D(ARRAY, ARRAYS) \
  8.     { \
  9.         int i,j; \
  10.         printf(ARRAYS " render:\n");\
  11.         for(i = 0; i < ghd.h; i++){\
  12.             for(j = 0; j < ghd.w; j++)\
  13.                 printf("[%02i] ", ARRAY[i][j]);\
  14.             putchar('\n');\
  15.         }\
  16.     }
  17.  
  18. const struct{ int w; int h; } ghd = {W, H}; // oops, apparently ghd is an internal variable for glibc. Compiler warned about it. 'ghd' is supposed to stand for "Grid Heap Dimensions", by the way
  19.  
  20. void do_stack(){
  21.     /* Allocates a 2D array via the stack.
  22.      * Static. Defined at compile time.
  23.      * Easy but inflexible.
  24.      * Also, the stack can only hold so much data
  25.      */
  26.     int grid[W][H] = {
  27.         { 0,  1,  2,  3,  4},
  28.         { 5,  6,  7,  8,  9},
  29.         {10, 11, 12, 13, 14},
  30.         {15, 16, 17, 18, 19},
  31.         {20, 21, 22, 23, 24},
  32.     };
  33.     printf("(2,2) from stack: %i\n", grid[2][2]);
  34.     REND_2D(grid, "Stack"); // Semicolon not necessary, but I put it anyway for readability
  35.     // There is no need to free a stack-allocated object. Actually, it will cause an error, so don't free a stack object.
  36. }
  37.  
  38. void do_heap(){
  39.     /* Allocates a 2D array via the heap.
  40.      * Dynamic. Defined at runtime.
  41.      * A little more difficult to get the hang of, but far more powerful
  42.      * Can hold a tremendous amount of data
  43.      */
  44.     int i,
  45.         j,
  46.         k = 0;
  47.     int **grid = malloc(sizeof(int *) * ghd.h);
  48.     /* It's a good idea to check, at this point, if grid == 0x0. Because if so, the allocation failed and could cause a segfault.*/
  49.     if(!grid){
  50.         perror("Couldn't allocate ~40 bytes!? Are you kidding me?"); // an addr is usually a long int when all is said and done, 64 bits * 5 pointers = 40b
  51.         exit(1);
  52.     }
  53.     for(i = 0; i < ghd.h; i++){
  54.         grid[i] = malloc(sizeof(int) * ghd.w);
  55.         for(j = 0; j < ghd.w; j++)
  56.             grid[i][j] = k++;
  57.     }
  58.     printf("(2,2) from heap: %i\n", grid[2][2]);
  59.     REND_2D(grid,  "Heap");
  60.     for(i = 0; i < ghd.h; i++){
  61.         free(grid[i]); // EVERY call to malloc must have a matching call to free, else you have a memory leak on your hands
  62.     }
  63.     free(grid);
  64. }
  65.  
  66. void do_linear() {
  67.     /* heap alloc with 1 dimension. Width is used to "simulate" the second dimension.
  68.      * When doing this, it is generally a good idea to put it inside of a struct
  69.      * containing metadata on the array, such that the whole thing can be passed
  70.      * as a struct pointer. Make your life easier. See <http://pastebin.com/UtfGvkkm> for an example implementation
  71.      */    
  72.     int *grid = malloc(sizeof(int) * ghd.w * ghd.h);
  73.     int i,
  74.         j;
  75.     for(i = 0; i < ghd.w * ghd.h; i ++)
  76.         grid[i] = i;
  77.  
  78.     // getting from linear is a little more involved...
  79.     printf("(2,2) from linear heap: %i\n", grid[2 + (2 * ghd.w)]);
  80.     /* 1 width = 1 "y", since it wraps around
  81.      * So 4 * width + 1 (down 4, right 1) is the same as (1,4) in a cartesian 4th-quadrant coordinate system such as a display
  82.      * Also, another way of writing grid[2 + (2 * ghd.w)] would be *(grid + 2 + (2 * ghd.w)).
  83.      */
  84.     printf("Linear render:\n");
  85.     for(i = 0; i < ghd.h; i++){
  86.         for(j = 0; j < ghd.w; j++)
  87.             printf("[%02i] ", grid[j + i * ghd.w]);
  88.         putchar('\n');
  89.     }
  90.     free(grid);
  91.     /* This is actually easier, IMO, than managing a 2D heap array.
  92.      * Well, except for when testing whether a coordinate lies "outside" of the
  93.      * boundaries. Then you have to get intimate with the modulus operator
  94.      * Like, to check against the left "wall", you'd have to check if
  95.      *     ((position-1) % width != width-1) && (position-1 > 0)
  96.      * Luckily, the left-edge boundary case is as complex as it gets.
  97.      *     Left    (position - 1) % width != width - 1 && position - 1 > 0
  98.      *     Right   (position + 1) % width != 0
  99.      *     Up      position - width >= 0
  100.      *     Down    position + width <= width * height
  101.      */
  102. }
  103.  
  104. int main(){
  105.     do_stack();
  106.     do_heap();
  107.     do_linear();
  108.     return 0;
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement