user1731810
user1731810

Reputation: 17

Using a pointer to a structure in a function that is declared in a header file

I have been searching all morning how to do this and I can't quite find what I am looking for. I should mention that I am fairly new to C.

I am trying to modulise my code (that is working until I try and do this)

Presently in the main code I have :

#include<stdio.h>
#include<rfftw.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include <fstream>
#include <iomanip>
#include<complex>
#include<omp.h>

struct basic_gal {
   double ra,dec,z,dist,fkp,nbar;
   double cp[3];
   double RSD[3];
};

struct basic_gal *gal; 
int NGAL_MAX =200000;

main() {

  if(!(gal = (struct basic_gal*)malloc(NGAL_MAX*sizeof(struct basic_gal))-1)) 
  printf("memory allocation problem for galaxies\n");

  etc etc..
}

I then go on to read in a file and allocate the various attributes to the structure. What I would like to do is pass the empty structure (or a pointer to it) to a function, fill in the elements of the structure in the function and then return it to use in my main program again.

This requires 3 files, the main.c, the header file, header.h and the file that contains the function actions bin_gals.c

In the header file I have

#include <stdlib.h>
#include <fstream>
#include <iomanip>
#include <stdio.h>
#include <math.h>
#include <string> 

void bin_NGP(int,int*,struct basic_gal*,int);

In the bin_gals.c file I have

#include "header.h"
#include <all_the_others>

void bin_NGP(int NGAL_MAX, int *NGAL, basic_gal *gal, int flag) {

/*read in files and add data etc*/

}

And in the main.c file I have

#include "header.h"
#include <all_the_others>

struct basic_gal {
   double ra,dec,z,dist,fkp,nbar;
   double cp[3];
   double RSD[3];
};
struct basic_gal *gal;  
int NGAL_MAX = 200000;

main() {

  if(!(gal = (struct basic_gal*)malloc(NGAL_MAX*sizeof(struct basic_gal))-1)) 
  printf("memory allocation problem for galaxies\n");

  int NGAL =0;
  int *ipNGAL =&NGAL;
  bin_NGP(NRAN_MAX,ipNGAL,gal,1);
}

The problem is that I think I am not passing the structure properly but cannot figure out how to do this.

My error messages look like

bin_gals.c: In function ‘void bin_NGP(int, int*, basic_gal*, int)’:
bin_gals.c:150: error: ISO C++ forbids comparison between pointer and integer
bin_gals.c:151: error: invalid types ‘basic_gal*[int*]’ for array subscript

and I am not sure how to fix this. Any help would be much appreciated!

EDIT: The actual content of the bin_NGP part of bin_gals.c is:

void bin_NGP(const char *data, int NGAL_MAX, int *NGAL, double *min_x, double *min_y        ,double *min_z, double *max_x, double *max_y ,double *max_z ,struct basic_gal *gal, int     flag) {

  FILE *fp_rand;
  if((fp_rand=fopen(data,"r"))==NULL) printf("data file %d not opened\n", flag);
  const int bsz=100; char buf[bsz];  
  fgets(buf, bsz, fp_rand);                         //header line
  while((fgets(buf, bsz, fp_rand))!=NULL) { 
  double ra, dec, cz; 
  sscanf(buf,"%lf %lf %lf\n",&ra,&dec,&cz);
  if(++NGAL>NGAL_MAX) { NGAL--; break; }
  gal[NGAL].ra = ra*pi/180.;
      gal[NGAL].dec = dec*pi/180.;
      gal[NGAL].z = cz;
      gal[NGAL].dist = calc_dp(gal[NGAL].z);
      gal[NGAL].cp[0] = (gal[NGAL].dist*cos(gal[NGAL].dec)*cos(gal[NGAL].ra)); 
      gal[NGAL].cp[1] = (gal[NGAL].dist*cos(gal[NGAL].dec)*sin(gal[NGAL].ra));
      gal[NGAL].cp[2] = (gal[NGAL].dist*sin(gal[NGAL].dec));
      if (flag ==1) {
        if (gal[NGAL].cp[0] > max_x) max_x = gal[NGAL].cp[0];
        if (gal[NGAL].cp[1] > max_y) max_y = gal[NGAL].cp[1];
        if (gal[NGAL].cp[2] > max_z) max_z = gal[NGAL].cp[2];

        if (gal[NGAL].cp[0] < min_x) min_x = gal[NGAL].cp[0];
        if (gal[NGAL].cp[1] < min_y) min_y = gal[NGAL].cp[1];
        if (gal[NGAL].cp[2] < min_z) min_z = gal[NGAL].cp[2];
      }         
    }
    fclose(fp_rand);
}

I tried to simplify the question by removing some of the input parameters.. maybe I was disguising a mistake.

EDIT: fixed. For clarity I have included the fixed code incase anyone has the same problem.

void bin_NGP(const char *data, int NGAL_MAX, int *NGAL, double *min_x, double *min_y ,double *min_z, double *max_x, double *max_y ,double *max_z ,struct basic_gal *gal, int flag) {

  FILE *fp_rand;
  if((fp_rand=fopen(data,"r"))==NULL) printf("data file %d not opened\n", flag);
  const int bsz=100; char buf[bsz];  
  fgets(buf, bsz, fp_rand);                         //header line
  while((fgets(buf, bsz, fp_rand))!=NULL) { 
  double ra, dec, cz; 
  sscanf(buf,"%lf %lf %lf\n",&ra,&dec,&cz);
  if(++(*NGAL) > NGAL_MAX) { *NGAL--; break; }
  gal[*NGAL].ra = ra*pi/180.;
      gal[*NGAL].dec = dec*pi/180.;
      gal[*NGAL].z = cz;
      gal[*NGAL].dist = calc_dp(gal[*NGAL].z);
      gal[*NGAL].cp[0] = (gal[*NGAL].dist*cos(gal[*NGAL].dec)*cos(gal[*NGAL].ra)); 
      gal[*NGAL].cp[1] = (gal[*NGAL].dist*cos(gal[*NGAL].dec)*sin(gal[*NGAL].ra));
      gal[*NGAL].cp[2] = (gal[*NGAL].dist*sin(gal[*NGAL].dec));
      if (flag ==1) {
        if (gal[*NGAL].cp[0] > *max_x) *max_x = gal[*NGAL].cp[0];
        if (gal[*NGAL].cp[1] > *max_y) *max_y = gal[*NGAL].cp[1];
        if (gal[*NGAL].cp[2] > *max_z) *max_z = gal[*NGAL].cp[2];

        if (gal[*NGAL].cp[0] < *min_x) *min_x = gal[*NGAL].cp[0];
        if (gal[*NGAL].cp[1] < *min_y) *min_y = gal[*NGAL].cp[1];
        if (gal[*NGAL].cp[2] < *min_z) *min_z = gal[*NGAL].cp[2];
      }         
  }
  fclose(fp_rand);
}

Upvotes: 0

Views: 209

Answers (2)

hmjd
hmjd

Reputation: 122001

You need to forward declare struct basic_gal* for the declaration of bin_NGP() as struct basic_gal is defined in main.c. However, the definition of struct basic_gal will need to be available to the definition of bin_NGP() so you should move its definition out of main.c into a separate module:

/* basic_gal.h */
#ifndef BASIC_GAL_DEFINITION
#define BASIC_GAL_DEFINITION

struct basic_gal {
   double ra,dec,z,dist,fkp,nbar;
   double cp[3];
   double RSD[3];
};

#endif

Note, if this is C you need to use struct basic_gal.


After edit, this is the offending line:

if(++NGAL>NGAL_MAX) { NGAL--; break; }

as NGAL is an int* and NGAL_MAX is an int. Dereference NGAL:

if(++*NGAL > NGAL_MAX) { (*NGAL)--; break; }

Dereference NGAL when using as array index:

gal[*NGAL].ra = ra*pi/180.;

Upvotes: 1

Maksim Satsikau
Maksim Satsikau

Reputation: 1494

You need to make your structure visible to both main.c and bin_gals.c. Modify your header bin_gals.h to something like:

 #include <stdlib.h> 
 #include <fstream> 
 #include <iomanip> 
 #include <stdio.h> 
 #include <math.h> 
 #include <string>  

 struct basic_gal { 
    double ra,dec,z,dist,fkp,nbar; 
    double cp[3]; 
    double RSD[3]; 
 }; 

 void bin_NGP(int,int*,struct basic_gal*,int); 

bin_gals.c then would look like

 #include "bin_gals.h"   
 #include <all_the_others>   

 void bin_NGP(int NGAL_MAX, int *NGAL, basic_gal *gal, int flag) {   

 /*read in files and add data etc*/   

 }   

And your main file would be like the following:

#include "bin_gals.h"      
#include <all_the_others>      

struct basic_gal *gal;        
int NGAL_MAX = 200000;      

main() {      

  if(!(gal = (struct basic_gal*)malloc(NGAL_MAX*sizeof(struct basic_gal))-1))       
  printf("memory allocation problem for galaxies\n");      

  int NGAL =0;      
  int *ipNGAL =&NGAL;      
  bin_NGP(NRAN_MAX,ipNGAL,gal,1);      
}      

Upvotes: 0

Related Questions