/*
* A program to print a spiral matrix of user-defined dimension:
* Ex: For dimension 5, produce
*
* 1 2 3 4 5
* 16 17 18 19 6
* 15 24 25 20 7
* 14 23 22 21 8
* 13 12 11 10 9
*/
#include <stdio.h>
#include <stdlib.h>
int **alloc_2D_int_array(int rows, int columns);
void free_2D_int_array(int **array);
int main(void)
{
int **a; /* to store the array */
int size; /* the dimension of the array */
int top, bottom, left, right; /* to traverse the 2D-array */
int i, j, value = 1;
printf("Enter the matrix dimension: ");
scanf("%d", &size);
/* allocate the 2D-array and test against failure */
if ((a = alloc_2D_int_array(size, size)) == NULL)
{
fprintf(stderr, "error: mamory not allocated\n");
return -1;
}
top = left = 0;
bottom = right = size - 1;
while (value <= size * size)
{
for (i = left; i <= right; ++i) /* process top row */
a[top][i] = value++;
++top;
for (i = top; i <= bottom; ++i) /* process right column */
a[i][right] = value++;
--right;
for (i = right; i >= left; --i) /* process bottom row */
a[bottom][i] = value++;
--bottom;
for (i = bottom; i >= top; --i) /* process left column */
a[i][left] = value++;
++left;
}
/* print the array generated */
for (i = 0; i < size; ++i)
{
for (j = 0; j < size; ++j)
putchar('\n');
}
free_2D_int_array(a); /* free the allocated array */
return 0;
}
/* alloc_2D_int_array: routine to allocate a 2D array of dimensions
* rows * columns. Internally, the 2D array is
* implemented in a one-dimensional array for efficiency. Returns the
* allocated array or NULL, if fails. The efficiency results from
* avoiding multiple calls to malloc() (& free() later)
*/
int **alloc_2D_int_array(int rows, int columns)
{
int **array, *temp;
int i;
/* allocating an int * array for storing rows' addresses */
if ((array = (int **) malloc(rows * sizeof(int *))) == NULL)
return NULL;
/* allocating memory for the entire array in a 1D array */
if ((temp = (int *) malloc(rows * columns * sizeof(int))) == NULL)
{
free(array); /* free the array of pointers if failed */
return NULL;
}
/* pointing the 2D-array pointers to right places in 1D-array */
for (i = 0; i < rows; ++i)
{
array[i] = temp;
temp += columns;
}
return array;
}
/* free_2D_int_array: routine to deallocate an array allocated using
* alloc_2D_int_array()
*/
void free_2D_int_array(int **array)
{
free(*array); /* free the internal 1D-array */
free(array); /* free the "2D-array" */
}