nested structures and initialization

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Sheldon

    #1

    nested structures and initialization

    Hi,

    Can anyone help with this problem with setting up nested structures
    and initializing them for use.
    I have created several structs and placed them in a super struct that
    I will then pass to some functions. I have defined them in the
    following manner:

    typedef struct trans Transient;
    typedef struct sats Satellites;
    typedef struct data Data;
    typedef struct super Super;

    struct data {
    float table_10[ROW*COL];
    float table_20[ROW*COL];
    float table_30[ROW*COL];
    float table_40[ROW*COL];
    float table_50[ROW*COL];
    float table_60[ROW*COL];
    float procent_amsu;
    };

    struct trans {
    char operationalfile[MAXSTR_LENGTH];
    char tunedfile[MAXSTR_LENGTH];
    char radarfile[MAXSTR_LENGTH];
    float amsu_flag[ARRAYSIZE];
    float radar[ARRAYSIZE];
    float pcpn1[ARRAYSIZE];
    float pcpn2[ARRAYSIZE];
    float pcpn3[ARRAYSIZE];
    };

    struct sats {
    Data *pN18;
    Data *pN17;
    Data *pN16;
    Data *pN15;
    Data *pM02;
    };

    struct super {
    Transient *TR;
    Satellites *Sp;
    Satellites *Su;
    Satellites *Au;
    Satellites *Wi;
    };

    Super* InitStruct(void );

    Now when I try to intialize the structure I get a bunch of errors. The
    InitStruct functions looks like this:

    int main() {

    Super *sptr;
    /* initializing the super structure */
    sptr = InitStruct();
    if (sptr == NULL) {
    fprintf(stderr, "Failed to initialize nested structure!\n");
    exit(EXIT_FAILU RE);
    } else {
    printf("Structu re now initialized!\n" );
    }
    return 1;
    }

    Super *InitStruct(voi d) {

    Super *sptr=NULL;

    if(!(sptr=mallo c(sizeof(Super) ))) {
    return NULL;
    }
    sptr->TR->operationalfil e=NULL;
    sptr->TR->tunedfile=NULL ;
    sptr->TR->radarfile=NULL ;
    sptr->TR->amsu_flag={0.0 };
    sptr->TR->radar={0.0};
    sptr->TR->pcpn1={0.0};
    sptr->TR->pcpn2={0.0};
    sptr->TR->pcpn3={0.0};

    sptr->Sp->N18->table_10={0.0} ;
    sptr->Sp->N18->table_20={0.0} ;
    sptr->Sp->N18->table_30={0.0} ;
    sptr->Sp->N18->table_40={0.0} ;
    sptr->Sp->N18->table_50={0.0} ;
    sptr->Sp->N18->table_60={0.0} ;
    sptr->Sp->N18->procent_amsu = 0.0;

    sptr->Sp->N17->table_10={0.0} ;
    sptr->Sp->N17->table_20={0.0} ;
    sptr->Sp->N17->table_30={0.0} ;
    sptr->Sp->N17->table_40={0.0} ;
    sptr->Sp->N17->table_50={0.0} ;
    sptr->Sp->N17->table_60={0.0} ;
    sptr->Sp->N17->procent_amsu = 0.0;
    .....

    }

    The errors begin with these:

    error: incompatible types in assignment
    error: incompatible types in assignment
    error: incompatible types in assignment
    error: parse error before '{' token
    error: parse error before '{' token

    and keeps on going.

    Could some please render some help in doing this correctly?

    Any help is truly appreciated.
    /S

  • Keith Willis

    #2
    Re: nested structures and initialization

    On Wed, 31 Oct 2007 09:18:29 -0000, Sheldon <shejo284@gmail .com>
    wrote:
    >Can anyone help with this problem with setting up nested structures
    >and initializing them for use.
    >I have created several structs and placed them in a super struct that
    >I will then pass to some functions. I have defined them in the
    >following manner:
    <snip>
    >typedef struct super Super;
    <snip>
    >struct super {
    Transient *TR;
    Satellites *Sp;
    Satellites *Su;
    Satellites *Au;
    Satellites *Wi;
    >};
    <snip>
    >Super *InitStruct(voi d) {
    >
    >Super *sptr=NULL;
    >
    if(!(sptr=mallo c(sizeof(Super) ))) {
    return NULL;
    }
    <snip remainder>

    Well the first thing that leaps out is that you've allocated space for
    a "struct super", which is simply five pointers. Nowhere do you
    allocate the memory that those pointers point at. I'm not even going
    to try and see what else is wrong :-)
    --
    PGP key ID 0xEB7180EC

    Comment

    • Sheldon

      #3
      Re: nested structures and initialization

      On 31 Okt, 10:44, Keith Willis <m...@privacy.n etwrote:
      On Wed, 31 Oct 2007 09:18:29 -0000, Sheldon <shejo...@gmail .com>
      wrote:
      >
      Can anyone help with this problem with setting up nested structures
      and initializing them for use.
      I have created several structs and placed them in a super struct that
      I will then pass to some functions. I have defined them in the
      following manner:
      >
      <snip>
      >
      typedef struct super Super;
      >
      <snip>
      >
      struct super {
      Transient *TR;
      Satellites *Sp;
      Satellites *Su;
      Satellites *Au;
      Satellites *Wi;
      };
      >
      <snip>
      >
      Super *InitStruct(voi d) {
      >
      Super *sptr=NULL;
      >
      if(!(sptr=mallo c(sizeof(Super) ))) {
      return NULL;
      }
      >
      <snip remainder>
      >
      Well the first thing that leaps out is that you've allocated space for
      a "struct super", which is simply five pointers. Nowhere do you
      allocate the memory that those pointers point at. I'm not even going
      to try and see what else is wrong :-)
      --
      PGP key ID 0xEB7180EC
      Ok, fair enough. How would you do it then? Let's say a 3 tier struct?
      Can you give an example that I can expland on?

      /S

      Comment

      • James Kuyper

        #4
        Re: nested structures and initialization

        Sheldon wrote:
        Hi,
        >
        Can anyone help with this problem with setting up nested structures
        and initializing them for use.
        I have created several structs and placed them in a super struct that
        I will then pass to some functions. I have defined them in the
        following manner:
        >
        typedef struct trans Transient;
        typedef struct sats Satellites;
        typedef struct data Data;
        typedef struct super Super;
        >
        struct data {
        float table_10[ROW*COL];
        float table_20[ROW*COL];
        float table_30[ROW*COL];
        float table_40[ROW*COL];
        float table_50[ROW*COL];
        float table_60[ROW*COL];
        float procent_amsu;
        };
        Why do you define 6 separate on-dimensional tables, rather than a single
        table with a leading dimension of 6? I suspect it will simplify the code
        that uses this structure.

        I would also recommend combining those typedefs with the corresponding
        struct declarations:

        typedef struct data {....} Data;

        I find that easier to understand; YMMV.
        struct trans {
        char operationalfile[MAXSTR_LENGTH];
        char tunedfile[MAXSTR_LENGTH];
        char radarfile[MAXSTR_LENGTH];
        float amsu_flag[ARRAYSIZE];
        float radar[ARRAYSIZE];
        float pcpn1[ARRAYSIZE];
        float pcpn2[ARRAYSIZE];
        float pcpn3[ARRAYSIZE];
        };
        Same comment about the pcpn family.
        struct sats {
        Data *pN18;
        Data *pN17;
        Data *pN16;
        Data *pN15;
        Data *pM02;
        };
        >
        struct super {
        Transient *TR;
        Satellites *Sp;
        Satellites *Su;
        Satellites *Au;
        Satellites *Wi;
        };
        >
        Super* InitStruct(void );
        >
        Now when I try to intialize the structure I get a bunch of errors. The
        InitStruct functions looks like this:
        >
        int main() {
        >
        Super *sptr;
        /* initializing the super structure */
        sptr = InitStruct();
        if (sptr == NULL) {
        fprintf(stderr, "Failed to initialize nested structure!\n");
        exit(EXIT_FAILU RE);
        } else {
        printf("Structu re now initialized!\n" );
        }
        return 1;
        }
        >
        Super *InitStruct(voi d) {
        That's a bad naming choice. InitSuper would be better. In general, you
        might have quite a lot of different structures to initialize. In this
        particular case, you have two of them, which is enough to justify not
        naming either function "InitStruct ".
        Super *sptr=NULL;
        >
        if(!(sptr=mallo c(sizeof(Super) ))) {
        return NULL;
        }
        At this point, none of the pointer members of *sptr have been
        initialized. Any use of the value of those pointers has undefined
        behavior. You need to allocate memory for each of the pointed at
        objects. Note: with this data structure you're going to have to make
        LOTS of separate memory allocations. If any one of those fails, then all
        of the allocations that succeeded should be free()d. This can get very
        complicated very fast. I avoid building structures like this, for
        precisely that reason. Therefore, the solution I use below is not the
        result of lots of experience with this kind of thing, but it's a lot
        better than other techniques I've seen used:

        bool successful = true;
        // Initialize to make sure that we can free() them without worrying
        // about whether they have been allocated:
        sptr->TR = NULL;
        sptr->Sp = NULL;
        // Similarly for other pointer members


        if(!(sptr->TR = malloc(sizeof Transient)) ||
        !(sptr->Sp = malloc(sizeof Satellites)) ||
        // Similarly for other pointer members
        ){
        successful = false;
        }

        ....
        sptr->TR->amsu_flag={0.0 };
        The curly brackets are a syntax error in this context. I think you are
        thinking of initialization syntax, but that doesn't apply to dynamically
        allocated memory. You'll have to write a loop to initialize that array.
        You'll be doing a lot of this, so I'd recommend creating a subroutine
        analogous to memset() which works on floats rather than unsigned char.

        If you use calloc() instead of malloc(), or use memset() after malloc(),
        on many implementations the floats will be properly initialized. That's
        because floating point formats which use a representation for 0.0 that
        has all of its bits set to 0 are fairly common. However, that's not
        guaranteed by the C standard, so you should not use that approach in
        code that needs to be portable.

        At this point, none of the pointer members of sptr->Sp have been
        initialized. Any attempt to use their current value has undefined
        behavior. You need to allocate memory for each one, just as I described
        above for the pointer members of sptr itself. You'll need to do this
        many times, so I recommend writing as subroutine to handle it. Later on,
        you'll need to deallocate all of that memory; again, you should use a
        subroutine. I'll need to refer to those routines down below, so I'll
        call them InitSatellite() and FreeSatellite() . Note: if the argument
        passed to FreeSatellite is null, it should return without doing
        anything, the same way that free() itself does.

        Remember to set successful = false if any of the InitSatellite() calls
        fails.

        This code should (with appropriate re-writes) be part of InitSatellite() :

        ....
        sptr->Sp->N18->table_10={0.0} ;
        ....

        if(!successful)
        { // Free everything, regardless of whether it's been allocated.
        free(sptr->TR);
        FreeSatellite(s ptr->Sp);
        free(sptr->Sp);
        // Similarly for other Satellites* members.
        free(sptr);
        return NULL;
        }

        return sptr;
        // Your original did not appear to include a return statement?
        }

        Comment

        • Mark Bluemel

          #5
          Re: nested structures and initialization

          Sheldon wrote:
          Hi,
          >
          Can anyone help with this problem with setting up nested structures
          and initializing them for use.
          I have created several structs and placed them in a super struct that
          I will then pass to some functions. I have defined them in the
          following manner:
          >
          typedef struct trans Transient;
          typedef struct sats Satellites;
          typedef struct data Data;
          typedef struct super Super;
          >
          struct data {
          float table_10[ROW*COL];
          float table_20[ROW*COL];
          float table_30[ROW*COL];
          float table_40[ROW*COL];
          float table_50[ROW*COL];
          float table_60[ROW*COL];
          float procent_amsu;
          };
          >
          struct trans {
          char operationalfile[MAXSTR_LENGTH];
          char tunedfile[MAXSTR_LENGTH];
          char radarfile[MAXSTR_LENGTH];
          float amsu_flag[ARRAYSIZE];
          float radar[ARRAYSIZE];
          float pcpn1[ARRAYSIZE];
          float pcpn2[ARRAYSIZE];
          float pcpn3[ARRAYSIZE];
          };
          >
          struct sats {
          Data *pN18;
          Data *pN17;
          Data *pN16;
          Data *pN15;
          Data *pM02;
          };
          >
          struct super {
          Transient *TR;
          Satellites *Sp;
          Satellites *Su;
          Satellites *Au;
          Satellites *Wi;
          };
          >
          Super* InitStruct(void );
          >
          Now when I try to intialize the structure I get a bunch of errors. The
          InitStruct functions looks like this:
          >
          int main() {
          >
          Super *sptr;
          /* initializing the super structure */
          sptr = InitStruct();
          if (sptr == NULL) {
          fprintf(stderr, "Failed to initialize nested structure!\n");
          exit(EXIT_FAILU RE);
          } else {
          printf("Structu re now initialized!\n" );
          }
          return 1;
          }
          >
          Super *InitStruct(voi d) {
          >
          Super *sptr=NULL;
          >
          if(!(sptr=mallo c(sizeof(Super) ))) {
          return NULL;
          }
          if (!(sptr->TR = malloc(sizeof(T ransient))) {
          return NULL;
          } /* and for the rest of the substructures */
          sptr->TR->operationalfil e=NULL;
          sptr->TR->tunedfile=NULL ;
          sptr->TR->radarfile=NULL ;
          sptr->TR->amsu_flag={0.0 };
          You can't in general assign arrays - this syntax is allowed in
          initializers only, I think.

          This should work though (I think) :-

          sptr->TR->amsu_flag=0;

          repeat as needed...

          Personally I'd have been inclined to go encapsulated and have functions
          to return initialized substructures, I think. (Too much exposure to OO?)

          Comment

          • James Kuyper

            #6
            Re: nested structures and initialization

            Mark Bluemel wrote:
            ....
            This should work though (I think) :-
            >
            sptr->TR->amsu_flag=0;
            amsu_flag is an array of floats. Therefore it's not a modifiable lvalue
            (6.3.2.1p1), so it can't be the left operand of an assignment operator
            (6.5.16p2).

            Comment

            • Mark Bluemel

              #7
              Re: nested structures and initialization

              James Kuyper wrote:
              Mark Bluemel wrote:
              ...
              >This should work though (I think) :-
              >>
              > sptr->TR->amsu_flag=0;
              >
              amsu_flag is an array of floats. Therefore it's not a modifiable lvalue
              (6.3.2.1p1), so it can't be the left operand of an assignment operator
              (6.5.16p2).
              I did wonder, but it compiled (gcc) even with strict options...

              Comment

              • Sheldon

                #8
                Re: nested structures and initialization

                On 31 Okt, 12:44, Mark Bluemel <mark_blue...@p obox.comwrote:
                Sheldon wrote:
                Hi,
                >
                Can anyone help with this problem with setting up nested structures
                and initializing them for use.
                I have created several structs and placed them in a super struct that
                I will then pass to some functions. I have defined them in the
                following manner:
                >
                typedef struct trans Transient;
                typedef struct sats Satellites;
                typedef struct data Data;
                typedef struct super Super;
                >
                struct data {
                float table_10[ROW*COL];
                float table_20[ROW*COL];
                float table_30[ROW*COL];
                float table_40[ROW*COL];
                float table_50[ROW*COL];
                float table_60[ROW*COL];
                float procent_amsu;
                };
                >
                struct trans {
                char operationalfile[MAXSTR_LENGTH];
                char tunedfile[MAXSTR_LENGTH];
                char radarfile[MAXSTR_LENGTH];
                float amsu_flag[ARRAYSIZE];
                float radar[ARRAYSIZE];
                float pcpn1[ARRAYSIZE];
                float pcpn2[ARRAYSIZE];
                float pcpn3[ARRAYSIZE];
                };
                >
                struct sats {
                Data *pN18;
                Data *pN17;
                Data *pN16;
                Data *pN15;
                Data *pM02;
                };
                >
                struct super {
                Transient *TR;
                Satellites *Sp;
                Satellites *Su;
                Satellites *Au;
                Satellites *Wi;
                };
                >
                Super* InitStruct(void );
                >
                Now when I try to intialize the structure I get a bunch of errors. The
                InitStruct functions looks like this:
                >
                int main() {
                >
                Super *sptr;
                /* initializing the super structure */
                sptr = InitStruct();
                if (sptr == NULL) {
                fprintf(stderr, "Failed to initialize nested structure!\n");
                exit(EXIT_FAILU RE);
                } else {
                printf("Structu re now initialized!\n" );
                }
                return 1;
                }
                >
                Super *InitStruct(voi d) {
                >
                Super *sptr=NULL;
                >
                if(!(sptr=mallo c(sizeof(Super) ))) {
                return NULL;
                }
                >
                if (!(sptr->TR = malloc(sizeof(T ransient))) {
                return NULL;
                } /* and for the rest of the substructures */
                >
                sptr->TR->operationalfil e=NULL;
                sptr->TR->tunedfile=NULL ;
                sptr->TR->radarfile=NULL ;
                sptr->TR->amsu_flag={0.0 };
                >
                You can't in general assign arrays - this syntax is allowed in
                initializers only, I think.
                >
                This should work though (I think) :-
                >
                sptr->TR->amsu_flag=0;
                >
                repeat as needed...
                >
                Personally I'd have been inclined to go encapsulated and have functions
                to return initialized substructures, I think. (Too much exposure to OO?)-Dölj citerad text -
                >
                - Visa citerad text -

                Hi,

                Thanks for your input. I took your advice and redesigned the script.
                Now things are done in smaller steps. But I still get a persistent
                error. Here are the new header and source files:
                <snip>

                typedef struct {
                float thres_tables[THRESHOLDS][ROW*COL];
                float procent_amsu;
                } Data;

                typedef struct {
                char operationalfile[MAXSTR_LENGTH];
                char tunedfile[MAXSTR_LENGTH];
                char radarfile[MAXSTR_LENGTH];
                float amsu_flag[ARRAYSIZE];
                double variables[COMP_VAR][ARRAYSIZE];
                Data* satid;
                } SUPER;

                SUPER* NewSatellite(vo id);

                /* pointers for sub strings */
                char *p;
                int counter;
                SUPER *retv=NULL;

                /* initializing the super structure */
                retv = NewSatellite();
                if (retv == NULL) {
                fprintf(stderr, "Failed to initialize nested structure!\n");
                exit(EXIT_FAILU RE);
                } else {
                printf("Structu re now initialized!\n" );
                }
                /* read the file list one at a time */
                file = fopen(datafile, "r");
                if (file == NULL) {
                fprintf(stderr, "Error: can't open file %s\n", datafile);
                exit(EXIT_FAILU RE);
                } else {
                printf("File successfully opened. Reading line by line...\n");
                j = 0;
                while (fgets(line,MAX LINE_LENGTH,fil e) != NULL) {
                printf("Line %d\t%s\n",++j,l ine);
                /* cutting the strings using delimiter ' ' */
                p = strtok(line," ");
                counter = 0;
                while (p != NULL) {
                if (counter == 0) strcpy(retv->tunedfile,p) ;
                p = strtok(NULL," ");
                printf("Sub string: %s\n",retv->tunedfile);
                counter++;
                }
                } /* end while */
                printf("EOF reached. Closing the file...\n");
                fclose(file);
                } /* else section if file is open without problem */
                return 1;
                } /* end main */

                /* Initialize the structure */
                SUPER* NewSatellite(vo id) {

                int i,j;
                SUPER *retv = NULL;

                if ((retv = malloc(sizeof(S UPER))) == NULL) {
                fprintf(stderr, "Failed to allocate memory for structure!\n");
                exit(EXIT_FAILU RE);
                }

                retv->operationalfil e = NULL;
                retv->tunedfile = NULL;
                retv->radarfile = NULL;
                retv->satid->procent_amsu = 0.0;
                for (i=0; i < COMP_VAR; i++) {
                for (j = 0; j < ARRAYSIZE; j++) {
                retv->variables[i][j] = 0.0;
                retv->amsu_flag[j] = 0.0;
                }
                }
                for (i=0; i < THRESHOLDS; i++) {
                for (j = 0; j < ROW*COL; j++) {
                retv->satid->thres_tables[i][j] = 0.0;
                }
                }
                return retv;
                };

                but the error remains:
                c: In function `main':
                c:20: warning: unused variable `i'
                c: In function `NewSatellite':
                c:73: error: incompatible types in assignment
                c:74: error: incompatible types in assignment
                c:75: error: incompatible types in assignment
                c:76: warning: statement with no effect


                What I am missing here?

                /S








                Comment

                • Keith Willis

                  #9
                  Re: nested structures and initialization

                  On Wed, 31 Oct 2007 13:11:09 -0000, Sheldon <shejo284@gmail .com>
                  wrote:
                  <much snippage>
                  >
                  retv->operationalfil e = NULL;
                  retv->tunedfile = NULL;
                  retv->radarfile = NULL;
                  <more snippage>
                  >c: In function `NewSatellite':
                  >c:73: error: incompatible types in assignment
                  >c:74: error: incompatible types in assignment
                  >c:75: error: incompatible types in assignment
                  >c:76: warning: statement with no effect
                  I told you in the email I sent you that your initialisation of these
                  strings was nonsense. You are trying to assign the value NULL to a
                  variable of type array-of-char. You need to set the first character
                  of the array-of-char to the value '\0', thus:

                  retv->operationalfil e[0] = '\0';

                  Alternatively, initialise the entire string to zeros (overkill):

                  memset(retv->operationalfil e, 0, sizeof retv->operationalfil e);
                  >What I am missing here?
                  Clues?
                  --
                  PGP key ID 0xEB7180EC

                  Comment

                  Working...