/* * Contrived example showing various ways of making 2D arrays: * * Program makes 2D array of "char" and fills with very simple pattern. * * Two command-line arguments -- rows and cols. */ #include #include void example_with_vla(int rows, int cols); void fill_2D_vla(int rows, int cols, char canvas[rows][cols], int top_row, int left_col, int fill_rows, int fill_cols, char fill); void print_vla(int rows, int cols, char canvas[rows][cols]); void example_with_malloc_1(int rows, int cols); void example_with_malloc_2(int rows, int cols); void fill_and_print_dynamic_array(int rows, int cols, char **canvas); void fill_2D(int rows, int cols, char **canvas, int top_row, int left_col, int fill_rows, int fill_cols, char fill); void print(int rows, int cols, char **canvas); /* main program */ int main(int argc, char *argv[]) { char *usage_msg_fmt = "usage: %s rows cols\n"; if (argc < 3) { printf(usage_msg_fmt, argv[0]); return EXIT_FAILURE; } char *endptr; int rows = strtol(argv[1], &endptr, 10); if (*endptr != '\0') { printf(usage_msg_fmt, argv[0]); return EXIT_FAILURE; } int cols = strtol(argv[2], &endptr, 10); if (*endptr != '\0') { printf(usage_msg_fmt, argv[0]); return EXIT_FAILURE; } if ((rows < 4) || (cols < 4)) { printf("rows, cols must both be at least 4\n"); return EXIT_FAILURE; } example_with_vla(rows, cols); example_with_malloc_1(rows, cols); example_with_malloc_2(rows, cols); return EXIT_SUCCESS; } /* * create, fill, and print array, representing it as a VLA */ void example_with_vla(int rows, int cols) { puts("array built as vla"); char canvas[rows][cols]; fill_2D_vla(rows, cols, canvas, 0, 0, rows, cols, '.'); fill_2D_vla(rows, cols, canvas, 1, 1, rows-2, cols-2, '+'); print_vla(rows, cols, canvas); } /* * fill part of 2D array (represented as a VLA): * rows, cols are dimensions of array * top_row, left_col are the top left corner to fill * fill_rows, fill_cols are the number of rows and cols to fill * "fill" is the character to use */ void fill_2D_vla(int rows, int cols, char canvas[rows][cols], int top_row, int left_col, int fill_rows, int fill_cols, char fill) { for (int i = top_row; i < top_row+fill_rows; i++) { for (int j = left_col; j < left_col+fill_cols; j++) { canvas[i][j] = fill; } } } /* * print 2D array (represented as a VLA) */ void print_vla(int rows, int cols, char canvas[rows][cols]) { puts(""); puts("array contents:"); puts(""); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { putchar(canvas[i][j]); } putchar('\n'); } puts(""); puts("pointers to rows:"); puts(""); for (int i = 0; i < rows; i++) { printf("%p\n", (void*) canvas[i]); } puts(""); } /* * create, fill, and print array, representing it an array of arrays * (pointers to rows), each allocated separately */ void example_with_malloc_1(int rows, int cols) { puts("array built as array of arrays"); char **canvas = malloc((sizeof *canvas) * rows); if (canvas == NULL) { printf("cannot get space for array row pointers\n"); exit(EXIT_FAILURE); } for (int r = 0; r < rows; ++r) { canvas[r] = malloc((sizeof *canvas[r])*cols); if (canvas[r] == NULL) { printf("cannot get space for array row\n"); exit(EXIT_FAILURE); } } fill_and_print_dynamic_array(rows, cols, canvas); for (int r = 0; r < rows; ++r) { free(canvas[r]); } free(canvas); } /* * create, fill, and print array, representing it an array of arrays * (pointers to rows), all pointing into one big 1D space containing * the whole array */ void example_with_malloc_2(int rows, int cols) { puts("array built as array of pointers plus 1D array"); char **canvas = malloc((sizeof *canvas) * rows); if (canvas == NULL) { printf("cannot get space for array row pointers\n"); exit(EXIT_FAILURE); } char *space = malloc((sizeof *space) * rows * cols); if (space == NULL) { printf("cannot get space for array\n"); exit(EXIT_FAILURE); } for (int r = 0; r < rows; ++r) { canvas[r] = space + r*((sizeof *space) * cols); } fill_and_print_dynamic_array(rows, cols, canvas); free(space); free(canvas); } /* * fill and print array, representing it an array of arrays * (pointers to rows) * (common code for example_with_malloc_1 and example_with_malloc_2) */ void fill_and_print_dynamic_array(int rows, int cols, char **canvas) { fill_2D(rows, cols, canvas, 0, 0, rows, cols, '.'); fill_2D(rows, cols, canvas, 1, 1, rows-2, cols-2, '+'); print(rows, cols, canvas); puts(""); } /* * fill part of 2D array (represented as an array of pointers to rows): * rows, cols are dimensions of array * top_row, left_col are the top left corner to fill * fill_rows, fill_cols are the number of rows and cols to fill * "fill" is the character to use */ void fill_2D(int rows, int cols, char **canvas, int top_row, int left_col, int fill_rows, int fill_cols, char fill) { for (int i = top_row; i < top_row+fill_rows; i++) { for (int j = left_col; j < left_col+fill_cols; j++) { canvas[i][j] = fill; } } } /* * print 2D array (represented as an array of pointers to rows): */ void print(int rows, int cols, char **canvas) { puts(""); puts("array contents:"); puts(""); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { putchar(canvas[i][j]); } putchar('\n'); } puts(""); puts("pointers to rows:"); puts(""); for (int i = 0; i < rows; i++) { printf("%p\n", (void*) canvas[i]); } puts(""); }