Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #define W 5
- #define H 5
- #define REND_2D(ARRAY, ARRAYS) \
- { \
- int i,j; \
- printf(ARRAYS " render:\n");\
- for(i = 0; i < ghd.h; i++){\
- for(j = 0; j < ghd.w; j++)\
- printf("[%02i] ", ARRAY[i][j]);\
- putchar('\n');\
- }\
- }
- 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
- void do_stack(){
- /* Allocates a 2D array via the stack.
- * Static. Defined at compile time.
- * Easy but inflexible.
- * Also, the stack can only hold so much data
- */
- int grid[W][H] = {
- { 0, 1, 2, 3, 4},
- { 5, 6, 7, 8, 9},
- {10, 11, 12, 13, 14},
- {15, 16, 17, 18, 19},
- {20, 21, 22, 23, 24},
- };
- printf("(2,2) from stack: %i\n", grid[2][2]);
- REND_2D(grid, "Stack"); // Semicolon not necessary, but I put it anyway for readability
- // There is no need to free a stack-allocated object. Actually, it will cause an error, so don't free a stack object.
- }
- void do_heap(){
- /* Allocates a 2D array via the heap.
- * Dynamic. Defined at runtime.
- * A little more difficult to get the hang of, but far more powerful
- * Can hold a tremendous amount of data
- */
- int i,
- j,
- k = 0;
- int **grid = malloc(sizeof(int *) * ghd.h);
- /* It's a good idea to check, at this point, if grid == 0x0. Because if so, the allocation failed and could cause a segfault.*/
- if(!grid){
- 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
- exit(1);
- }
- for(i = 0; i < ghd.h; i++){
- grid[i] = malloc(sizeof(int) * ghd.w);
- for(j = 0; j < ghd.w; j++)
- grid[i][j] = k++;
- }
- printf("(2,2) from heap: %i\n", grid[2][2]);
- REND_2D(grid, "Heap");
- for(i = 0; i < ghd.h; i++){
- free(grid[i]); // EVERY call to malloc must have a matching call to free, else you have a memory leak on your hands
- }
- free(grid);
- }
- void do_linear() {
- /* heap alloc with 1 dimension. Width is used to "simulate" the second dimension.
- * When doing this, it is generally a good idea to put it inside of a struct
- * containing metadata on the array, such that the whole thing can be passed
- * as a struct pointer. Make your life easier. See <http://pastebin.com/UtfGvkkm> for an example implementation
- */
- int *grid = malloc(sizeof(int) * ghd.w * ghd.h);
- int i,
- j;
- for(i = 0; i < ghd.w * ghd.h; i ++)
- grid[i] = i;
- // getting from linear is a little more involved...
- printf("(2,2) from linear heap: %i\n", grid[2 + (2 * ghd.w)]);
- /* 1 width = 1 "y", since it wraps around
- * 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
- * Also, another way of writing grid[2 + (2 * ghd.w)] would be *(grid + 2 + (2 * ghd.w)).
- */
- printf("Linear render:\n");
- for(i = 0; i < ghd.h; i++){
- for(j = 0; j < ghd.w; j++)
- printf("[%02i] ", grid[j + i * ghd.w]);
- putchar('\n');
- }
- free(grid);
- /* This is actually easier, IMO, than managing a 2D heap array.
- * Well, except for when testing whether a coordinate lies "outside" of the
- * boundaries. Then you have to get intimate with the modulus operator
- * Like, to check against the left "wall", you'd have to check if
- * ((position-1) % width != width-1) && (position-1 > 0)
- * Luckily, the left-edge boundary case is as complex as it gets.
- * Left (position - 1) % width != width - 1 && position - 1 > 0
- * Right (position + 1) % width != 0
- * Up position - width >= 0
- * Down position + width <= width * height
- */
- }
- int main(){
- do_stack();
- do_heap();
- do_linear();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement