Results 1 to 26 of 26

Thread: Different structures in one array, how?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Nov 2001
    Location
    fl
    Posts
    92

    Different structures in one array, how?

    I've 7 structures. Smallest structure has 2 variables and largest 8.

    struct invA_typ { // smallest struct
    long A;
    long B;
    }

    struct invG_typ { // largest struct
    long A;
    ...
    long G;
    }

    I've to deal with all the structs as one array to loop trough them, how can I do that?

    Thanks in advance

  2. #2
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    You can nest structs

    Code:
    typedef struct{
        struct{
               long x;
               long y;
        }a;
        struct{
              long x;
              long y;
              long z;
        }b;
    } myrecord;
    
    struct myrecord recs[200];
    
    for (int i=0;i<200li++){
             recs[i].a.x=0;
             recs[i].a.y=0;
             recs[i].b.x=0;
             recs[i].b.y=0;
             recs[i].b.z=0;
    }  // how to reference the elements

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Nov 2001
    Location
    fl
    Posts
    92
    I guess that will take a lot of memory. I can just stick to the largest struct but still thats too much memory.

    anyways thanks for the reply
    Last edited by XfoxX; Jan 24th, 2003 at 04:57 PM.

  4. #4
    Fanatic Member riis's Avatar
    Join Date
    Nov 2001
    Posts
    551
    I think you should use an array of pointers for this. All elements in this array should hold a pointer to one of your structures. Memory management will be harder this way, but it's the way I think it costs the least memory.

    Jim: I think an union is better than a structure of structures. An union will be as large as the largest element it holds, in this case structure g.
    Code:
    typedef union{
        struct{
               long x;
               long y;
        }a;
        struct{
              long x;
              long y;
              long z;
        }b;
    } myrecord;
    But, as XfoxX said, this costs apparently too much memory.

  5. #5
    Fanatic Member riis's Avatar
    Join Date
    Nov 2001
    Posts
    551
    Hmm, XfoxX, I was thinking of another approach to your problem. Since you're always using the same datatype, and since that data type is integral, you can place everything in one single array. Just forget about the structures. How? The first element in the array will indicate the size of the former structure, which is i. The next i elements will hold the data of the various elements of the structure. Then the following element has the size of the next structure, j. The next j elements have the data. Etcetera.

    An example:
    0: 3 (which is the size of structure B)
    1: first element of structure B
    2: second element of structure B
    3: third element of structure B
    4: 6 (structure G)
    5: first element of G
    6: second element of G

    10: sixth element of G
    11: 2 (structure A)
    12: first element yadda yadda

    A disadvantage is that you cannot see the total number of structures at a glance. You have to go through the array, but this should be fast enough.

  6. #6
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    All of those are half-hearted solutions that impose more work on the programmer. And they are prone to bugs.

    You should rethink your design. Why do you have to have 7 different structs in one array?
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Nov 2001
    Location
    fl
    Posts
    92
    Cornedbee, because fields in each type of record varies. I would loop from each type of record seprately, but I need to make the looping process shorter and faster. riis you have a good idea, although it might make difficult to trace errors, but it's fast and takes less memory. Unfortunately fields have different data type. I guess keeping an array of pointers might be the best approach.

  8. #8
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    You could have a slightly simpler version of polymorphism here:
    Code:
    struct proxy {
        int type;
        void *obj;
    };
    
    struct big {
        int A, B, C, D, E, F, G;
    };
    
    struct small {
        int A, B, C;
    };
    
    enum types { t_big, t_small };
    
    const size_t SIZE = 50;
    proxy records[SIZE];
    
    for(size_t i = 0; i < SIZE; ++i) {
        if(i % 2) {
            records[i].type = t_big;
            records[i].obj = (void*)new big;
        } else {
            records[i].type = t_small;
            records[i].obj = (void*)new small;
        }
    }
    ...then you can read them as necessary. I wouldn't really recommend that though. It may be partially more efficient, but all that casting to void*...ugh. Far simple to use polymorphism:
    Code:
    struct small {
        int A, B, C;
    };
    
    struct big : public small {
        int D, E, F, G;
    };
    
    const size_t SIZE = 50;
    small* records[SIZE];
    
    for(size_t i = 0; i < SIZE; ++i) {
        if(i % 2) {
            records[i].obj = new big;
        } else {
            records[i].obj = new small;
        }
    }
    I think. I haven't compiled that so...
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  9. #9
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Yeah, but that only works in C++.

    Hmm....

    Actually I think that having seperate arrays for each data type would be the fastest and most memory efficient. Every way of stuffing them all into one array wastes memory in some way and the identification takes time.
    The only thing that would increase would be code size, and that is usually the least critical factor (except in bootstraps )
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  10. #10
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    And for polymorphism you need RTTI enabled to find out what this really is.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  11. #11
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    If you can't avoid it I would recommend a "variable node linked list". A linked list that has different node types.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  12. #12
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    My first option will work (with a couple of changes) in C.

    As for multiple arrays, yeah, that would be a fair bit quicker.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  13. #13
    Fanatic Member riis's Avatar
    Join Date
    Nov 2001
    Posts
    551
    Multiple arrays will only be a good idea if you're sure the order of all records doesn't matter. Else a linked list, as CornedBee suggested, might be better. But, in that case, you have to go through all the list if you want to extract the data of the last record.

  14. #14
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Make it pinned at both ends, and doubly-linked. That way you only have to go 1/2 way at maximum. That is, if you know more-or-less where it is.

    However, regarding the multiple arrays idea...you could always have another array, that holds the indexes in the two other arrays. However, for one of the arrays, there is a high bit set, that you can test for and mask off. This will limit you to half the range of the value you store in the "root" array, so I'm skeptical, but it should work unless you have more than about 2 milliard items.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  15. #15
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    But he has 7 structures, not just 2. Those were just examples.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  16. #16
    Fanatic Member riis's Avatar
    Join Date
    Nov 2001
    Posts
    551
    So, what's wrong with the array of pointers concept I mentioned? (Aside from the memory management aspects.)

  17. #17
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Nothing. But the memory management and the ID of the structs are not fun.

    You approach is good. I just don't think it's the best, but that depends on the exact situation.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  18. #18
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    A "best" solution is frequently unattainable, in practice.

    In this situation it might be productive to look at *why* we're trying to do this. No point solving the wrong problem, if there's a better solution to a different problem, solving the original problem as a by-product
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  19. #19
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Very true. That's what my first post was about.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  20. #20
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Oh yeah. Forgotten about that one
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  21. #21
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    Use a masthead-like array. Read and write the record essentially blindly.

    Let the array remember what kind of record it has in it.

    Code:
    struct recptr{      // masthead
         short type;
         void *p;
    }
    struct r1{
         long a;
         char b[20];
    }
    struct r2{
         char a;
         double b;
         char c;
    }
    struct r3{
         char a[40];
         float b;
         short c;
    }
    // and so on to r7
    int rsizes[8];
    struct recptr lst[200];
    int currecptr=(-1);
    .............
    
    rsizes[1]=sizeof(struct r1);
    rsizes[2]=sizeof(struct r2);
    .........
    rsizes[7]=sizeof(struct r7);
    
    void add_array_element(short type){
         currecptr++; // allocate a record of the type you need 
         lst[currecptr].type=type;
         lst[currecptr].p =(void*) calloc(1,rsizes[type]+1);
    }
    void readrecord(int rectoread, FILE *instream){
         //  read it from file
         fread(lst[rectoread].p,rsizes[lst[rectoread].type],1,instream);      
    }
    void write record((int rectowrite, FILE *ostream){
         //  write it to file
         fread(lst[rectowrite].p,rsizes[lst[rectowrite].type],1,ostream);      
    }

  22. #22
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    PS:

    The 'too-much-memory' argument is nice, but unless you're working in 16 bit environments, it usually is not valid. Memory mAngement in 32-bit environments lets you read/write VERY large
    (100MB files) on boxes with less memory than the file size. I

    Plus, the compiler aligns members of a struct - packs them with filler to word-align integral members - which uses up more memory.

    We have to read stuff written by DOS boxes (hand held meter uploads) on a unix box. We have to outsmart the unix compiler
    by doing something like the above, except we don't use
    Code:
    rsize[3]=sizeof(struct whatever);
    because the structs may or may not have padding, whereas the stuff that the DOS box creates are not packed. We cast each segment to a known data type using a map that gives the sequences and kinds of datatypes.

  23. #23
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    The 'too-much-memory' argument is nice, but unless you're working in 16 bit environments, it usually is not valid. Memory mAngement in 32-bit environments lets you read/write VERY large
    (100MB files) on boxes with less memory than the file size.
    That you have a lot of memory is no reason not to save as much as you reasonably can.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  24. #24
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    BTW, doesn't gcc have an option to tell it not to pack structs?
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  25. #25
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    -fno-pack-structs or something like that.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  26. #26

    Thread Starter
    Lively Member
    Join Date
    Nov 2001
    Location
    fl
    Posts
    92
    thanks for the input

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width