I am learning C and trying new things to test what I can do. I have written code which produces a Mandelbrot set with a given resolution (RES) which is #define RES
in the .h file. This works and produces good output for resolutions less than 321. For some reason when RES > 321
then the code no longer executes.
I am running using GCC and plotting the output using Gnuplot. I have tried debugging with a debugger however for RES > 321
the main
function no longer gets run? I have added a print in the first line of main()
to see and this doesn't get run. An executable is made and the program compiles with no errors?
#include <stdio.h>
#include <math.h>
#define MAX_DEPTH 100
#define RES 321
typedef struct complex_t {
double re;
double im;
} complex;
void init_complex_grid(complex complex_grid[RES][RES], double left, double right, double top, double bottom);
int converge(complex a);
complex add_complex(complex a, complex b);
complex square_complex(complex a);
double mag_complex(complex a);
void output_grid(unsigned int grid[RES][RES]);
int main(void) {
// printf("HERE\n");
int i, j;
unsigned int convergence_grid[RES][RES];
complex complex_grid[RES][RES];
init_complex_grid(complex_grid, -2.5, 1, 1, -1);
for (i = 0; i < RES; i++) {
for (j = 0; j < RES; j++) {
convergence_grid[i][j] = converge(complex_grid[i][j]);
}
}
output_grid(convergence_grid);
return 0;
}
void init_complex_grid(complex complex_grid[RES][RES],
double left, double right,
double top, double bottom) {
int i, j;
double restep = (top - bottom) / RES;
double imstep = (right - left) / RES;
for (i = 0; i < RES; i++) {
for (j = 0; j < RES; j++) {
complex_grid[i][j].re = left + j * imstep;
complex_grid[i][j].im = bottom + i * restep;
}
}
}
int converge(complex a) {
complex z = { 0, 0 };
int cnt = 0;
while (cnt <= MAX_DEPTH && mag_complex(z) <= 2) {
z = add_complex(square_complex(z), a);
cnt++;
}
return cnt;
}
complex add_complex(complex a, complex b) {
complex added = { a.re + b.re, a.im + b.im };
return added;
}
complex square_complex(complex a) {
complex b;
b.re = a.re * a.re - a.im * a.im;
b.im = 2 * a.re * b.im;
return b;
}
double mag_complex(complex a) {
return sqrt(a.re * a.re + a.im * a.im);
}
void output_grid(unsigned int grid[RES][RES]) {
FILE *f = fopen("mandelbrot.dat", "w");
int i, j;
for (i = 0; i < RES; i++) {
for (j = 0; j < RES; j++) {
fprintf(f, "%d ", grid[i][j]);
}
fprintf(f, "\n");
}
fclose(f);
printf("\nFILE CLOSED\n");
}
I also added the line printf("\nFILE CLOSED\n");
so I would know that the output had been written to the file but this does not get run either with RES > 321
.
You are defining too much data with automatic storage in the main()
function: either make the large arrays global, static or allocate them from the heap.
Here is a simple fix you can try:
int main(void) {
int i, j;
static unsigned int convergence_grid[RES][RES];
static complex complex_grid[RES][RES];
init_complex_grid(complex_grid, -2.5, 1, 1, -1);
for (i = 0; i < RES; i++) {
for (j = 0; j < RES; j++) {
convergence_grid[i][j] = converge(complex_grid[i][j]);
}
}
output_grid(convergence_grid);
return 0;
}
Here is an alternative using heap allocation:
int main(void) {
int i, j;
unsigned int (*convergence_grid)[RES] = calloc(sizeof(*convergence_grid), RES);
complex (*complex_grid)[RES] = calloc(sizeof(*complex_grid), RES);
if (!convergence_grid || !complex_grid) {
fprintf(stderr, "cannot allocate arrays\n");
return 1;
}
init_complex_grid(complex_grid, -2.5, 1, 1, -1);
for (i = 0; i < RES; i++) {
for (j = 0; j < RES; j++) {
convergence_grid[i][j] = converge(complex_grid[i][j]);
}
}
output_grid(convergence_grid);
free(complex_grid);
free(convergence_grid);
return 0;
}