CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    Join Date
    May 2009
    Location
    Boston
    Posts
    375

    help with complex struct (or class)

    I have some data that I need to be able to store with assignment. This is basically a location to store the value of a float.

    The float is called ET,

    Each data value has three characteristics,
    order (1-4) -> int OR
    type1 (1-100) -> int T1
    type2(1-100) -> int T2

    I am thinking of something along the lines of,

    Code:
       struct values {  
          int type1[100];
          int type2[100];
         float finalValue;
       } order [4];
    I would like to be able to assign something like,

    order[OR].type1[T1].type2[T2].finalValue = ET

    Something like this would self-document the storage location for any combination of order and types. It would also allow for both storage and recovery without evaluating lots of conditionals.

    I know that the struct above is completely wrong, but I can seem to locate how to set this up. This could probably also be done with a multidimensional array, but I would prefer a struct or class. This doesn't seem like it should be all that difficult, but I can't seem to think it though.

    I suppose this is really a kind of search tree, but that is getting beyond the programming I know well.

    LMHmedchem
    Last edited by LMHmedchem; September 29th, 2009 at 04:54 PM.

  2. #2
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: help with complex struct (or class)

    Quote Originally Posted by LMHmedchem View Post
    I would like to be able to assign something like,

    order[OR].type1[T1].type2[T2].finalValue = ET
    Well, you can derive the class hierarchy needed to be able to compile this code.
    Going from left to right, you first need a variable order who's type is an array-like object. So you can do something like
    Code:
    struct Order {};
    Order order[4];
    Now, you need Order to have a member variable type1 who's type is again an array-like object.
    Code:
    struct Type1 {};
    struct Order {
        Type1 type1[100];
    };
    Order order[4];
    I'll leave the rest up to you.

    Btw, I'm not sure if you are using C or C++ here (it seems the latter). If you are using C++, I would advise you to change your static arrays to std::vector's.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  3. #3
    Join Date
    May 2009
    Location
    Boston
    Posts
    375

    Re: help with complex struct (or class)

    Quote Originally Posted by D_Drmmr View Post
    Btw, I'm not sure if you are using C or C++ here (it seems the latter). If you are using C++, I would advise you to change your static arrays to std::vector's.
    Thank you very much for the information, I think this is a big help.

    I am compiling this as cpp (gpp), but I think that most everything I am using is c, meaning I am not implementing any classes or objects, etc. I do most of my programming in FORTRAN, but I code some routines in cpp when I need to use a library function or need structured data. This gets called from a g77 routine.

    If I understand you correctly,
    Code:
    Order order[4];
    
    struct Order {
        Type1 type1[100];
    };
    
    struct Type1 {
        Type2 type2[100];
    };
    
    struct Type2 {
       float eVal;
       int eCount;
       std::vector vertexNumI[50];
       std::vector vertexNumJ[50];
       std::vector vertexTypeI[50];
       std::vector vertexTypeJ[50];
       int vertexNumIct;
       int vertexNumJct;
       int vertexTypeIct;
       int vertexTypeJct;
    };
    So for order=2, type1=16, type2=35,
    Code:
    order[2].type1[16].type2[35].eVal
    order[2].type1[16].type2[35].eCount
    etc.

    Or, more generically for the example I gave,
    Code:
    order[OR].type1[T1].type2[T2].eVal = ET
    would assign the value of ET to the correct storage location.

    My alternative is an array like array[4][100][100][3], but that wouldn't allow me to store everything that I need and I think would be inefficient. This doesn't seem any different than something like an employee database, company.department.employeeNumber.vacationDays, or something of the sort. It there a better data structure method to handle this sort of thing, or is the struct of struct that best way to go? This is all assigned and evaluated in very procedural code, so it doesn't need to be interactive in any way.

    LMHmedchem

  4. #4
    Join Date
    May 2009
    Location
    Boston
    Posts
    375

    Re: help with complex struct (or class)

    This is what I set up,

    Code:
       struct Order {
          Type1 type1[100];
       };
       struct Type1 {
          Type2 type2[100];
       };
       struct Type2 {
          float edgeVal;
          int edgeCount;
       };
    
       Order order[4];
    When I compile, I get the following errors,

    Code:
    In function `void load_edgevalues__(int*, int*, int*, float*)':
    error: `Type1' does not name a type
    error: `Type2' does not name a type
    error: 'struct load_edgevalues__(int*, int*, int*, float*)::Order' has no member named 'type1'
    error: 'struct load_edgevalues__(int*, int*, int*, float*)::Order' has no member named 'type1'
    What am I missing here?

    LMHmedchem

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: help with complex struct (or class)

    Quote Originally Posted by LMHmedchem View Post
    This is what I set up,

    Code:
       struct Order {
          Type1 type1[100];
       };
       struct Type1 {
          Type2 type2[100];
       };
    C++ compiles from the top down. The compiler does not know what "Type1" is when it sees the Order struct. When you compile in C++, all definitions, functions, variables, etc. must either have been declared or defined before-hand. There is no "two-pass" compilation done in C++.

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    May 2009
    Location
    Boston
    Posts
    375

    Re: help with complex struct (or class)

    So I just reversed the order to,
    Code:
    struct Type2 {
       float eVal;
       int eCount;
       int vertexNumI[50];
       int vertexNumJ[50];
       int vertexTypeI[50];
       int vertexTypeJ[50];
       int vertexNumIct;
       int vertexNumJct;
       int vertexTypeIct;
       int vertexTypeJct;
    };
    struct Type1 {
        Type2 type2[100];
    };
    struct Order {
        Type1 type1[100];
    };
    
       Order order[4];
    and it seems to work fine.

    Do you believe that this is the best solution for storing and accessing this kind of data?

    There was a suggestion to use std::vector instead of the int[] in Type2. Would this let me dispense with the array position counters? I know that the size of vectors can be changed and that they have other functions that arrays don't, but I don't know too much more than that, or even the syntax for declaring and assigning/reading.

    LMHmedchem

  7. #7
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: help with complex struct (or class)

    Quote Originally Posted by LMHmedchem View Post
    Do you believe that this is the best solution for storing and accessing this kind of data?
    The biggest problem with this code is that it requires a lot of space on the stack. That may cause a problem on some systems, but can be resolved by allocating the Orders on the heap, e.g. by using a std::vector.
    Code:
    // This would allocate on the stack
    //Order order[4];
    
    // But this will allocate on the heap
    std::vector<Order> order(4);
    You can access the elements in the same way as with the static array.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  8. #8
    Join Date
    May 2009
    Location
    Boston
    Posts
    375

    Re: help with complex struct (or class)

    I have set up the following,

    In a .h file, struct.h,
    Code:
    using namespace std;
    
    struct Type2 {
       float eVal;
       int eCount;
       int NumI[50];
       int NumJ[50];
       int TypeI[50];
       int TypeJ[50];
       int Ict;
       int Jct;
    };
    struct Type1 {
        Type2 type2[100];
    };
    struct Order {
        Type1 type1[100];
    };
    
    std::vector<Order> order[4];
    In a src file,
    Code:
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <iterator>
    #include "struct.h"
    
    using namespace std;
    
       int i;               // loop iterator
       int tmpIct, tmpJct;  // temp position counters
    
       tmpIct = order[*LRDR].type1[*K1].type2[*K2].Ict;
       tmpJct = order[*LRDR].type1[*K1].type2[*K2].Jct;
    
       order[*LRDR].type1[*K1].type2[*K2].NumI[tmpIct] = *ITMP;
       order[*LRDR].type1[*K1].type2[*K2].Ict ++;
       order[*LRDR].type1[*K1].type2[*K2].NumJ[tmpJct] = *JTMP;
       order[*LRDR].type1[*K1].type2[*K2].Jct ++;
    
       order[*LRDR].type1[*K1].type2[*K2].eVal = *ET;
       order[*LRDR].type1[*K1].type2[*K2].eCount ++;
    This works if I use Order order [4]; in the .h, but if I use std::vector<Order> order[4]; I get

    error: 'class std::vector<Order, std::allocator<Order> >' has no member named 'type1'

    at compile. If I use std::vector<Order> order(4); it compiles, but I get a runtime error. Clearly there are some things about vectors that I don't understand.

    LMHmedchem

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: help with complex struct (or class)

    Quote Originally Posted by LMHmedchem View Post
    This works if I use Order order [4]; in the .h, but if I use std::vector<Order> order[4]; I get
    Do you know what that definition means? You are declaring an array of vectors. Is that what you want to do? You want a single vector. In that single vector, you will be storing 4 Orders, not an array of 4 vectors.

    Secondly, this declaration:
    Code:
    std::vector<Order> order(4);
    Declares a single vector, and creates 4 entries in the vector on construction. This is why this definition would be equivalent to your original array definition.

    You must understand this syntax, as it really has nothing to do with vectors at all. That syntax is just a declaration of a class, and you are constructing it with a single argument (the 4). The class just happens to be std::vector<Order>, but all C++ templated classes that are declared and constructed follow similar syntax.
    it compiles, but I get a runtime error.
    Your problem has nothing to do with vectors. It has everything to do with making sure that your index into that array or vector is valid. For example, if you try to read or write to the 5th entry in a vector or array that can only hold 4 items, the behaviour of the program is undefined. You may also be doing some other out-of-bounds accesses within each Order. There is no way to know without seeing the code.

    So your program crashing is another issue altogether, and it really doesn't have to do with vector.
    Clearly there are some things about vectors that I don't understand.
    Why not write a small program, or read a tutorial, so that you become familiar with vectors. There really isn't anything hard about vectors at all. It is one of the simplest templated STL classes to use

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    May 2009
    Location
    Boston
    Posts
    375

    Re: help with complex struct (or class)

    I am quite sure that I don't know the definition, thank you for the explanation.

    The reason that I have isolated the runtime error to the vector construction is that I get the error even when there is nothing in the function. Meaning that when my function is empty,

    Code:
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <iterator>
    #include "struct.h"
    
    using namespace std;
    
    extern "C" {
       void load_edgeinfo__(int *LRDR, int *K1, int *K2, int *ITMP, int *JTMP, float *ET);
    }
    
    void load_edgeinfo__(int *LRDR, int *K1, int *K2, int *ITMP, int *JTMP, float *ET) {
    
    
    }
    I get a runtime error when it is called. This is the header file,
    Code:
    using namespace std;
    
    // data structure to hold bond-type information
    struct Type2 {
       float eVal;
       int eCount;
       int NumI[50];
       int NumJ[50];
       int TypeI[50];
       int TypeJ[50];
       int Ict;
       int Jct;
    };
    struct Type1 {
        Type2 type2[100];
    };
    struct Order {
        Type1 type1[100];
    };
    
    std::vector<Order> order(4);
    I actually get an error even if the empty function is not called.

    I have been looking at some documentation on vectors, but it is difficult to get going when the program just blows up. I don't know if this function being called from FORTRAN adds to the complexity of not. I would guess not, because it is all compiled as cpp under g77.

    I looked at this,
    http://www.cppreference.com/wiki/stl/vector/start
    but I did not find it to be overly enlightening.

    LMHmedchem

  11. #11
    Join Date
    Apr 1999
    Posts
    27,449

    Re: help with complex struct (or class)

    Quote Originally Posted by LMHmedchem View Post
    I have been looking at some documentation on vectors, but it is difficult to get going when the program just blows up. I don't know if this function being called from FORTRAN adds to the complexity of not. I would guess not, because it is all compiled as cpp under g77.
    You should forget about Fortran for the moment and convince yourself that there is nothing wrong with the vector class.
    Code:
    #include <vector>
    struct Type2 {
       float eVal;
       int eCount;
       int NumI[50];
       int NumJ[50];
       int TypeI[50];
       int TypeJ[50];
       int Ict;
       int Jct;
    };
    struct Type1 {
        Type2 type2[100];
    };
    struct Order {
        Type1 type1[100];
    };
    
    std::vector<Order> order(4);
    
    int main()
    {
        order[0].type1[0].type2[30].eVal = 1.0F;
    }
    That code sets that particular eVal value to 1.0F. So there is no difference between this syntax and array syntax. Compile and run this program. When you see this working, then you will formally familiarize yourself with how to use vectors.

    Also, since this is the C++ forum, a "program" consists of int main() and within that, code that exercises the functions in question so that the problem is duplicated. Having C++ called from another language brings about a whole set of issues that are outside the realm of the C++ language and library. The only thing I can tell you is that the code I posted above cannot crash -- if it does, then you have a buggy compiler or environment.

    Regards,

    Paul McKenzie

  12. #12
    Join Date
    May 2009
    Location
    Boston
    Posts
    375

    Re: help with complex struct (or class)

    Well I am going to have to wade back through this and see if I can find where the issue is. I will start by compiling the code you posted and see if that works. Then I will call the function from a simple Fortran main, etc. I suppose it wouldn't hurt to re-install my gp/gcc/g77.

    Co-compiling cpp and Fortran is not really a big problem under GNU since it's all compiled as cpp under the hood. There are some quirky things involved in passing variables, you can't pass a string back to Fortran, because it doesn't know what a string is, variables passed from Fortran need to be referenced as pointers in cpp, etc. You basically have to keep two sets of variables, one for each code base, but other than that, I have never had issues with cpp library functions that are called from the cpp code. That is the main reason that I stick in cpp functions in the first place. Problems usually occur in communication between the FMAIN and the called function.

    Thank you very much for the help, I will post what I find.

    LMHmedchem

  13. #13
    Join Date
    May 2009
    Location
    Boston
    Posts
    375

    Re: help with complex struct (or class)

    I tried the following,

    I set up the following .src, test.cpp,
    Code:
    #include <vector>
    #include <iostream>
    
    struct Type2 {
       float eVal;
       int eCount;
       int NumI[50];
       int NumJ[50];
       int TypeI[50];
       int TypeJ[50];
       int Ict;
       int Jct;
    };
    struct Type1 {
        Type2 type2[100];
    };
    struct Order {
        Type1 type1[100];
    };
    
    std::vector<Order> order(4);
    
    int main()
    {
        order[0].type1[0].type2[30].eVal = 1.0;
        std::cout << order[0].type1[0].type2[30].eVal << std::endl;
    }
    I did,
    g++ -c test.cpp
    g++ -o text.exe test.o
    ./test.exe

    There are no compile or link errors, warnings, or messages, but I got the following at runtime,
    $ ./test.exe
    102 [main] _test 1708 _cygtls::handle_exceptions: Error while dumping state (probably
    corrupted stack)
    Segmentation fault (core dumped)

    Can you spot anything that is wrong, I can't. I guess I will re-install, unless there are other ideas.

    LMHmedchem

  14. #14
    Join Date
    Apr 1999
    Posts
    27,449

    Re: help with complex struct (or class)

    Quote Originally Posted by LMHmedchem View Post
    Can you spot anything that is wrong, I can't. I guess I will re-install, unless there are other ideas.

    LMHmedchem
    Looks like a bad install. It may be the stream (cout) or the vector class has an issue (unless there is a mistake in the code I posted, but I don't think there is one).

    Try this simpler program:
    Code:
    #include <vector>
    std::vector<int> IntArray(4);
    int main()
    {
       IntArray[0] = 10;
    }
    This should compile and run. If it does, add the cout and see if it goes through OK or blows up.

    Regards,

    Paul McKenzie

  15. #15
    Join Date
    May 2009
    Location
    Boston
    Posts
    375

    Re: help with complex struct (or class)

    I did a re-install.

    This compiles and runs,
    Code:
    #include <vector>
    #include <iostream>
    
    std::vector<int> IntArray(4);
    int main()
    {
       IntArray[0] = 10;
       std::cout << IntArray[0];
    }
    and prints 10 as expected.

    This is still not working,
    Code:
    #include <vector>
    #include <iostream>
    
    struct Type2 {
       float eVal;
       int eCount;
       int NumI[50];
       int NumJ[50];
       int TypeI[50];
       int TypeJ[50];
       int Ict;
       int Jct;
    };
    struct Type1 {
        Type2 type2[100];
    };
    struct Order {
        Type1 type1[100];
    };
    
    std::vector<Order> order(4);
    
    int main()
    {
        order[0].type1[0].type2[30].eVal = 1.0F;
    //    std::cout << order[0].type1[0].type2[30].eVal << std::endl;
    }
    It will compile, but I get,
    $ ./_test.exe
    1 [main] _test 724 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack)
    Segmentation fault (core dumped)
    at runtime. I get the error with or without the cout. If I add a test print before the order[0].type1[0] statement, I still get the error, so the program is not able to initialize.

    I tried this on a linux box and didn't have any problems, so there is still a local problem here somewhere. It is odd that the simple program worked fine.

    LMHmedchem

Page 1 of 2 12 LastLast

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

Featured