2D array pointer access segmentation fault in C -
i'm trying write code conway's game of life in c. have problems 2d array contain universe. show parts of code cause me problems. there 2 problems can't handle.
#include <stdio.h> #include <stdlib.h> #include "file2ppm.h" typedef enum { false, true } bool; void *allocatememoryfor2darray(int x, int y); //allocate memory 2d array void initializeuniversefromfile(char* path, int x, int y, int array[x][y]); //set values of cells file void initializeuniverserandomly(int x, int y, int array[x][y]); //set random values int getnumberofcolumns (file *file); //get number of columns in file (ydim of universe) int getnumberoflines (file *file); //get number of lines in file (xdim of universe) void print2darray (int x, int y, int array[x][y]); //print 2d array void setdimensionsfromfile(char* path,int* xdim, int* ydim, int* xdimb, int* ydimb);//set dimensions of universe int main(int argc, char * argv[]) { int i, j, n; //loop indexes int nsteps; //number of generations int im, ip, jm, jp; //neighbour boundaries int ydim, xdim; //universe boundarier defined user (living area); int xdimb, ydimb; //universe boundaries expanded each side 1 int nsum, isum; //sum of neighbours, sum of alive cells after iteration //int **old, **new; //universe int (*old)[xdimb]; //universe int (*new)[xdimb]; //universe float x; //to randomize first population char *inputpath; //path file ixdimbtial uxdimbverse char *outputpath; //path output ppm files //temporary copy int ydim_copy, xdim_copy; printf("argc: %d\n", argc); switch (argc){ case 4: //read initial universe file //take arguments nsteps = atoi(argv[1]); //get number of iterations outputpath = argv[2]; //get path outputimages inputpath = argv[3]; //file initialize uxdimbverse; setdimensionsfromfile(inputpath, &xdim, &ydim, &xdimb, &ydimb); old = allocatememoryfor2darray(xdimb, ydimb); //alocate memory expanded universes new = allocatememoryfor2darray(xdimb, ydimb); printf("before initialize: ydim: %d, xdim: %d\n", ydim, xdim); //here values //tmp copy ydim_copy = ydim; xdim_copy = xdim; initializeuniversefromfile(inputpath, xdim, ydim, old); printf("after initialize: ydim: %d, xdim: %d\n", ydim, xdim); //and here 1 dim changed ydim = ydim_copy; //i took copy avoid problem xdim = xdim_copy; printf("after taking copy: ydim: %d, xdim: %d\n", ydim, xdim);//here dimensions again memcpy (new, old, xdimb*ydimb*sizeof(old[xdimb][ydimb])); //copy old new break; default: printf("usage: %s iter_number, output_name, ydim, xdim\n", argv[0]); printf("or\n"); printf("usage: %s iter_number, output_name, ixdimbtial_input_name\n", argv[0]); printf("note: initial file have in ./data/\n"); return 1; } print2darray(xdim, ydim, old); //this works fine printf("in main: ydim: %d, xdim: %d\n", ydim, xdim); printf("%d\n", old[0][0]); //this works fine printf("%d\n", old[2][2]); //segmentation failure return 0; } void *allocatememoryfor2darray(int x, int y){ int (*array)[y] = malloc( sizeof(int[x][y]) ); //allocate memory if (array == null) { /* check return of malloc */ perror("malloc"); exit(exit_failure); } return array; } int getnumberofcolumns (file *file){ int ydim = 0; char ch; { ch = getc(file); //get 1 char file if (ch == '\n') //if ch new line { rewind(file); //move file pointer beginxdimbng of file return ydim; //found number of columns } else ++ydim; }while (ch != eof); } int getnumberoflines (file *file){ int xdim = 0; char ch; { ch = getc(file); //get 1 char file if(ch == '\n') //if new line { ++xdim; //increase xdim (another row) } }while(ch != eof); rewind(file); //move file pointer beginxdimbng of file return xdim; } void print2darray (int x, int y, int array[x][y]) { int i, j; printf("x: %d, y: %d\n", x, y); (i = 1; <= x; ++i) { (j = 1; j <= y; ++j) { printf("%d ", array[i][j]); } printf("\n"); } } void setdimensionsfromfile(char* path, int* xdim, int* ydim, int* xdimb, int* ydimb) { file *file; int i,j; file = fopen(path, "r"); //open file if (file) { *ydim = getnumberofcolumns (file); *xdim = getnumberoflines (file); *xdimb = *xdim + 2; // add 2 left , right torus topology *ydimb = *ydim + 2; if (*xdim > 0 && *ydim > 0) { printf("uxdimbverse dimension %d x %d\n", *xdim , *ydim); } else { perror("wrong initialize file"); exit(exit_failure); } fclose(file); //close file } else { perror("open initialize file error"); exit(exit_failure); } } void initializeuniversefromfile(char* path, int x, int y, int array[x][y]) { file *file; int i,j; file = fopen(path, "r"); //open file if (file) { //ixdimbtialize array char *ch; (i = 1; <= x; i++) { //printf("i: %d ", i); (j = 1; j <= y; j++) { //printf("j: %d ", j); if (fscanf(file, "%c", ch) != 1) { perror("read error\n"); } else if (isdigit((unsigned char)*ch)) { printf("%d", atoi(ch)); array[i][j] = atoi(ch); } else { //printf("numer znaku: %d ", ch); j--; } } printf("\n"); } printf("done reading\n"); fclose(file); //close file } else { //file open error perror("open initialize file error"); exit (exit_failure); } printf("in initialize ydim: %d, xdim: %d\n", x, y); } void initializeuniverserandomly(int x, int y, int array[x][y]) { int i, j; float r; (i = 1; <= x; i++) { (j = 1; j <= y; j++) { r = rand() / ((float)rand_max + 1); if (r<0.5) { array[i][j] = i*x+j; } else { array[i][j] = i*x+j; } } } }
problem 1: set dimensions of universe (variables xdim , ydim). print them in line 45 (check comment //here values good). call initializeuniversefromfile(inputpath, xdim, ydim, old);
, 1 of dimensions values changed. have no idea why. that's why make temporary copy of variables, because i've spent 2 hours looking error. print out variables @ end of initializeuniversefromfile
function, , fine. when i'm in main again (line 50), value changed. minor problem. worse is:
problem 2 have pointer int (*old)[xdimb];
xdimb xdim+2 bigger xdim
i initialize array function allocatememoryfor2darray(xdimb, ydimb)
then this:
print2darray(xdim, ydim, old); //this works fine printf("in main: ydim: %d, xdim: %d\n", ydim, xdim); //dimensions fine printf("%d\n", old[0][0]); //this works fine (i=0; i<=xdim; ++i) printf("%d ", old[0][i]; //this works fine printf("%d\n", old[2][2]); //segmentation failure
printing whole array function fine printing values first row fine printing value middle of array create error.
i set dimensions of universe (variables xdim , ydim)
you need these contain valid numbers before declare vlas int (*old)[xdimb];
, int (*new)[xdimb];
. move these vla declarations latter point in program, when xdim
, ydim
have known, verified values.
Comments
Post a Comment