How do you create a table with variables from multiple structs?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • bmerlover
    New Member
    • Jul 2007
    • 49

    How do you create a table with variables from multiple structs?

    Hi, I would like to create an array of struct variables inside a table to avoid using many if/else and/or switch/case statements. I have attached a simple example of what I am trying to do, it doesn't work. For the table "sTablePtr" I see different values than what I set, when I dereference it with a "&" it just shows me the addresses of the variables. However at the end, when I do print out the values, by just using the structs themselves, they print out the values correctly.

    My structure declarations must remain a pointer. Any help would be greatly appreciated. I will continue to look for a solution and post it if I do find one. Thanks

    To be clear, what I am trying to do is have sTablePtr[i] show me the correct values I set, in this case I want the for loop to print out 1, 2 and 3. If there is a different way of doing this, I am open to it as long as I can use a table of my struct variables to avoid many if statements.

    Code:
    #define MAX_CNT 3
    
    typedef struct
    {
       int nNum;
       int nCnt;   
    }sDummy1;
    
    typedef struct
    {
       int nAge;
       double epsilon;
       int nCnt;   
    }sDummy2;
    
    typedef struct
    {
       int nData;
       double pi;
       int nCnt;   
    }sDummy3;
    
    sDummy1 *s1;
    sDummy2 *s2;
    sDummy3 *s3;
    
    static char * sInfo[MAX_CNT] = {
       (char *)s1, // removing the & from here makes no difference
       (char *)&s2,
       (char *)&s3
    };
    
    static int * sTablePtr[MAX_CNT] = {
       &s1->nCnt,
       &s2->nCnt,
       &s3->nCnt
    };
    
    /* when i declare a table like this, it just crashes with a memory error
       basically as if i was writing to a non allocated section of memory
    static int sTable[MAX_CNT] = {
       s1->nCnt,
       s2->nCnt,
       s3->nCnt
    };
    
    */
    void main()
    {   
       int i;
       int nValuesOver2;
          
       s1 = (sDummy1*) malloc (sizeof(sDummy1));
       s2 = (sDummy2*) malloc (sizeof(sDummy2));
       s3 = (sDummy3*) malloc (sizeof(sDummy3));
       
       memset(s1, 0, sizeof(sDummy1));
       memset(s2, 0, sizeof(sDummy2));
       memset(s3, 0, sizeof(sDummy3));
    
       s1->nCnt = 1;
       s1->nNum = 1;
    
       s2->nAge = 2;
       s2->nCnt = 2;
       s2->epsilon = 2.7;
    
       s3->nCnt = 3;
       s3->nData = 3;
       s3->pi = 3.14;
    
       for(i = 0; i < MAX_CNT; i++)
       {
          // this just prints values 4, 16, and 16 for s1, s2 and s3 respectively
          // when i dereference it (&sTablePtr[i]) it prints the address of the variables
          // when i debug it, the values are blank inside
          printf("%d: %d\n", i, sTablePtr[i]);
          // I am trying to print out the values 1, 2 and 3 here.
          if(sTablePtr[i] > 2)
          {
             nValuesOver2++;
          }
       }
    
       // These print the correct values
       printf("S1: %d\n", s1->nCnt); // prints 1
       printf("S2: %d\n", s2->nCnt); // prints 2
       printf("S3: %d\n", s3->nCnt); // prints 3
     
       printf("There are %d values over 2", nValuesOver2);
     
       _getch();
    }
    Code:
    // keep in mind i have many structs, it's not limited to 3   
    // I'm trying to avoid this  
    
    if(s1->nCnt > 2)
       nValuesOver2++;
    
    if(s2->nCnt > 2)
       nValuesOver2++;
       
    if(s3->nCnt > 2)
       nValuesOver2++
    
    etc....
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    Are you familiar with polymorphism?

    If you use C you wil have 100 times the work over C++.

    This is a common programming situation. Your table will contain addresses of objects where each object can be of a different struct.

    If yu are not familiar with polymorphism, read: http://bytes.com/topic/c/insights/79...polymorphism-c.

    Post again to continue the discussion.

    Comment

    • bmerlover
      New Member
      • Jul 2007
      • 49

      #3
      thank you for the quick reply, unfortunately I have to use the language C. It can not be C++ or any other language.

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        OK.
        You can use a discriminator. This is a struct with a pointer to the actual data:

        Code:
        struct MyType
        {
           void*  theData;
           unsigned int theType;
        };
        So you create an object of sme struct of your, let's call it Dummy2 and assgn its address to theData member of the discriminator:

        Code:
        MyType* TablePtr[10];
        MyType* discrim = new malloc(sizeof(MyType));
        sDummy2* stuff = new malloc(sizeof(sDummy2));
        /*populate stuff with values.*/
        /*store the address of stuff inside discrim*/
        discrim->theData = stuff;
        /*put in the discriminator. Let's say an sDummy2 is
          #define DUMMY2 10. You will have a #define like this for each of yur structs */
        discrim->theType = DUMMY2;
        
        /*Then insert into the array */
        TablePtr[0] = discrim;
        To process data you write functions for each of your structs that take MyType* arguments:

        Code:
        int AnsDummy2Function(MyType* arg)
        {
           if (arg->theType != DUMMY2)
           {
        
              /* arg is not an sDummy2 */
              return 1; /*fail */
            }
            /*process arg as an sDummy2
        
            return 0;   /*success */  
        
        }
        Now if you run a loop from 0 to 9 and call AnsDummy2Functi on with each TablePtr element, only the elements that point to an SDummy2 will get processsed.

        BTW: I just typed up this post without compiling it. I hope you see the idea here.
        Last edited by weaknessforcats; Aug 1 '12, 07:30 PM. Reason: fix code error

        Comment

        • bmerlover
          New Member
          • Jul 2007
          • 49

          #5
          Thanks a lot for your help! That pretty much did the trick, I made a few slight modifications but it's following your idea. Thanks again!

          Code:
          #include <stdlib.h>
          #include <stdio.h>
          #include <conio.h>
          
          #define MAX_CNT 3
           
          typedef struct
          {
             int nNum;
             int nCnt;   
          }sDummy1;
           
          typedef struct
          {
             int nAge;
             double epsilon;
             int nCnt;   
          }sDummy2;
           
          typedef struct
          {
             int nData;
             double pi;
             int nCnt;   
          }sDummy3;
           
          typedef struct 
          {
             void*  theData;
             unsigned int theType;
          }MyType;
          
          #define DUMMY1 1
          #define DUMMY2 2
          #define DUMMY3 3
          
          int AnsDummy2Function(MyType* arg)
          {
             if (arg->theType != DUMMY2)
             { 
                /* arg is not an sDummy2 */
                return 1; /*fail */
              }
              /*process arg as an sDummy2 */
           
              return 0;   /*success */   
          }
          
          void main()
          {  
             int i = 0;
             int nValid = 0;
             MyType* TablePtr[MAX_CNT] = {malloc(sizeof(MyType)),
                                          malloc(sizeof(MyType)),
                                          malloc(sizeof(MyType))};
             
             sDummy1* s1 = malloc(sizeof(sDummy1));
             sDummy2* s2 = malloc(sizeof(sDummy2));
             sDummy3* s3 = malloc(sizeof(sDummy3));
             
             sDummy1* sd1 = malloc(sizeof(sDummy1));
             sDummy2* sd2 = malloc(sizeof(sDummy2));
             sDummy3* sd3 = malloc(sizeof(sDummy3));
             
             /*populate stuff with values.*/
             s1->nCnt = 1;
             s1->nNum = 4;
          
             s2->nCnt = 2;   
             s2->nAge = 5;
             s2->epsilon = 2.7;
          
             s3->nCnt = 3;
             s3->nData = 15;
             s3->pi = 3.14;
                
             TablePtr[0]->theData = s1;
             TablePtr[0]->theType = DUMMY1;
             
             TablePtr[1]->theData = s2;
             TablePtr[1]->theType = DUMMY2;
                   
             TablePtr[2]->theData = s3;
             TablePtr[2]->theType = DUMMY3;
                
             for(i = 0; i < MAX_CNT; i++)
             {
                nValid = AnsDummy2Function(TablePtr[i]);
             }
          
             sd1 = (sDummy1*)TablePtr[0]->theData;
             sd2 = (sDummy2*)TablePtr[1]->theData;
             sd3 = (sDummy3*)TablePtr[2]->theData;
          
             printf("SD1: %d\n", sd1->nCnt); // prints 1
             printf("SD2: %d\n", sd2->nCnt); // prints 2
             printf("SD3: %d\n", sd3->nCnt); // prints 3
          
             _getch();
          }

          Comment

          Working...