CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 20 of 20
  1. #16
    Join Date
    Apr 1999
    Posts
    27,449

    Re: help with complex struct (or class)

    The item takes up a lot of stack space. In Visual Studio 2008, a checking of the stack is done when the vector gets created, and a "stack overflow" error occurs. That's probably the reason you are having problems.

    The struct is, give or take, around 800 bytes. So by the time you get to the Order struct, you need around 8 megabytes of stack to accommodate the Order struct.

    There are various solutions:

    1) Make those arrays inside the struct vectors also OR

    2) Allocate the Order from the heap instead of making it a global object OR

    3) Make it a std::vector<Order*> and dynamically create the Order using "new Order", and place that in the vector:
    Code:
    std::vector<Order*> order(4);
    //...
    for (int i = 0; i < 4; ++i )
       order[i] = new Order;
    //...
    //.. delete them when you're done.
    for (int i = 0; i < 4; ++i )
        delete order[i];
    Smart pointers are an alternative to the above, but is essentially the same thing.

    There are other solutions, but these three are the ones that are most prominent in my mind at the moment.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; October 1st, 2009 at 07:53 PM.

  2. #17
    Join Date
    May 2009
    Location
    Boston
    Posts
    364

    Re: help with complex struct (or class)

    I have attempted to make all of the arrays vectors,
    Code:
    #include <vector>
    using namespace std;
    
    struct Type2 {
       float eVal;
       int eCount;
       std::vector<int> NumI;
       std::vector<int> NumJ;
       std::vector<int> TypeI;
       std::vector<int> TypeJ;
       int Ict;
       int Jct;
    };
    struct Type1 {
       std::vector<Type2> type2;
    };
    struct Order {
       std::vector<Type1> type1;
    };
    
    std::vector<Order> order(4);
    I can't seem to determine where the vector sizes go for the vectors declared in the struct. If I add a dimension inside the struct, std::vector<int> NumI(50), it won't compile. When I remove them, it will compile, but won't run. I have tried a few things such as,

    Code:
    std::vector<Order> type1(100);
    std::vector<Type1> type2(100);
    std::vector<int> atomNumI(50);
    std::vector<int> atomNumJ(50);
    std::vector<int> atomTypeI(50);
    std::vector<int> atomTypeJ(50);
    but I don't seem to be getting anywhere. If there is no dimension in the declaration, then there must be an initialization somewhere, but I can't seem to work out the syntax. I have looked for documentation on vectors in a struct. There is allot on vector of structs, but not the other way around.

    LMHmedchem

  3. #18
    Join Date
    Apr 1999
    Posts
    27,449

    Re: help with complex struct (or class)

    Quote Originally Posted by LMHmedchem View Post
    I have attempted to make all of the arrays vectors,
    Code:
    #include <vector>
    using namespace std;
    
    struct Type2 {
       float eVal;
       int eCount;
       std::vector<int> NumI;
       std::vector<int> NumJ;
       std::vector<int> TypeI;
       std::vector<int> TypeJ;
       int Ict;
       int Jct;
    };
    struct Type1 {
       std::vector<Type2> type2;
    };
    struct Order {
       std::vector<Type1> type1;
    };
    
    std::vector<Order> order(4);
    I can't seem to determine where the vector sizes go for the vectors declared in the struct. If I add a dimension inside the struct, std::vector<int> NumI(50), it won't compile. When I remove them, it will compile, but won't run. I have tried a few things such as,

    Code:
    std::vector<Order> type1(100);
    std::vector<Type1> type2(100);
    std::vector<int> atomNumI(50);
    std::vector<int> atomNumJ(50);
    std::vector<int> atomTypeI(50);
    std::vector<int> atomTypeJ(50);
    but I don't seem to be getting anywhere. If there is no dimension in the declaration, then there must be an initialization somewhere, but I can't seem to work out the syntax. I have looked for documentation on vectors in a struct. There is allot on vector of structs, but not the other way around.

    LMHmedchem
    OK, the issue you have is understanding what to do when one of your members is a class, and you need to construct it on initialization. You need to look up what an "initialization list" is in C++. This allows you to initialize members of a structure that need "special" initialization when constructed:
    Code:
    struct Type2 {
       float eVal;
       int eCount;
       std::vector<int> NumI;
       std::vector<int> NumJ;
       std::vector<int> TypeI;
       std::vector<int> TypeJ;
       int Ict;
       int Jct;
    
       Type2() : NumI(50), NumJ(50), TypeI(50), TypeJ(50),
                       Ict(0), Jct(0), eVal(0.0F), eCount(0) { }
    };
    //...
    Order order; // This will create a single order, and initialize the members according to the default constructor.
    In C++, a struct and a class are the same thing except that the members in a struct default to public access (and derivation from a struct is defaulted to public). So in the struct above, there is a default constructor added. This constructor initializes all of the members -- note the vector initiailzations.

    In some shops, it is a requirement that all structs and classes have some sort of construction that sets the elements to a known value when an object is created. This is automatically done above with the default constructor.

    None of this exists in 'C', so you can't leverage any knowledge of 'C' to what I've shown you above (as a matter of fact, it may be detrimental to think 'C' when writing C++). If you don't have a good C++ book handy, I suggest you get one, since what I've explained is basic C++ (initialization lists).

    Regards,

    Paul McKenzie

  4. #19
    Join Date
    May 2009
    Location
    Boston
    Posts
    364

    Re: help with complex struct (or class)

    *** EDIT ***

    I changed the declaration of the vector to,
    std::vector<Order> order(5);

    and it runs so far. The possible values for order are 1-4, so I thought if the dimension was (4) I could allocate from [0] to [4], but that is 5 positions, so I guess I need to declare (5) arrays. Is that right?

    *** END EDIT ***


    Thank you for the help, I am definitely making progress. The code will compile and run partway before it fails.

    This is the .h,
    Code:
    #include <vector>
    using namespace std;
    
    struct Type2 {
       std::vector<int> NumI;
       std::vector<int> NumJ;
       std::vector<int> TypeI;
       std::vector<int> TypeJ;
       float eVal;
       int eCount;
       int Ict;
       int Jct;
       Type2() : NumI(50), NumJ(50), TypeI(50), TypeJ(50),
                 eVal(0.0F), eCount(0),Ict(0), Jct(0) { }
    };
    struct Type1 {
       std::vector<Type2> type2;
       Type1() : type2(100) { }
    };
    struct Order {
       std::vector<Type1> type1;
       Order() : type1(100) { }
    };
    
    std::vector<Order> order(4);
    If I just call the empty function, it will run without error. I can also print specific initialized values from the struct and run without error.

    std::cout << "Ict 0.0.0 " << order[0].type1[0].type2[0].Ict << std::endl;
    std::cout << "Ict 0.0.1 " << order[0].type1[0].type2[1].Ict << std::endl;

    If I generalize, even to print,
    Code:
       ord = *LRDR;  // *LRDR, *K1, *K2, passed to the function in the call
       k1 = *K1;
       k2 = *K2;
    
       std::cout << "Ict " << order[ord].type1[k1].type2[k2].Ict << std::endl;
    the program progresses through the first 18 of the edges, and then fails before printing the
    order[ord].type1[k1].type2[k2].Ict value for the 19 edge (should print 0). I can print the values of ord, k1, and k2 and they are correct.

    I checked, and I cannot print the initialized value for,

    std::cout << "Ict 4.0.1 " << order[4].type1[0].type2[0].Ict << std::endl;

    so it seems to be not allocating enough space for all 4 order vectors, or something of that sort.

    Do I need to create/construct each instance of order as I need it? It seem as if I may have missed a constructor somewhere. I am treating this like an array that exists and is just populated at various locations, but I guess I am not thinking about this correctly.

    I have several books on C++ and have worked though parts of them doing examples etc. I have never used more than the basics, which are C like and very similar to Fortran excepting the syntax. The examples I have read and worked through are simplistic and often seem too far separated for actual implementations to be of much help. I will read more later this afternoon.

    LMHmedchem
    Last edited by LMHmedchem; October 2nd, 2009 at 01:29 PM.

  5. #20
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863

    Re: help with complex struct (or class)

    you are calling a invalid index on the order vector,

    Just like C-style arrays, vectors are 0 indexed. So the vector

    std::vector<Order> order(4);

    has four valid entries

    order[0], order[1], order[2] and order[4]
    Wakeup in the morning and kick the day in the teeth!! Or something like that.

    "i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."

Page 2 of 2 FirstFirst 12

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