Touble with passing a reference to vector of vectors of objects

Discussion in 'C++' started by hardwareman, Jun 28, 2005.

  1. hardwareman

    hardwareman Guest

    Hi Folks,

    I can work around this problem, but it shows a problem in my
    understanding of how things should work. Any ideas are appreciated.

    Thanks,
    Hardwareman

    When the following subroutine is put inline the results are expected.
    When the reference to the vector is passed, the reference has the
    correct sizes but the 'Print' member function spews almost random junk.

    BLAH is an unordinary user class containing scalars.

    typedef vector<BLAH> EntryBram_T ;
    typedef vector<EntryBram_T> Expected_T ;

    void C_PrintExpected ( Expected_T & expected ) {
    for (int i=0 ; i < expected.size() ; i++) {
    Msg(MSG_LOW, "%m: C_PrintExpected: terminal=%d list size=%d\n",
    i, expected.size() ) ;
    int j = 0 ;
    // print out all expected entries
    while (j < expected.size() ) {
    (expected)[j].Print(j++) ;
    }
    }
    }


    The calling function:

    expected[ term ].push_back( EntryBram[original_start] ) ;
    Msg(MSG_LOW, "%m: Print what we just pushed\n") ;
    (expected[ term ].end()-1)->Print(original_start) ; // this is
    fine
    C_PrintExpected(expected) ; // THIS IS
    WRONG

    // This inline code works as expected
    for (int i=0 ; i < expected.size() ; i++) {
    Msg(MSG_LOW, "%m: C_PrintExpected inline: terminal=%d list
    size=%d\n",
    i, expected.size() ) ;
    int j = 0 ;
    // print out all expected entries
    while (j < expected.size() ) {
    (expected)[j].Print(0) ;
    j++ ;
    }
    }

    ////////////////
    RUN RESULTS:

    BAD :
    C_PrintExpected: terminal=0 list size=1
    BLAH::print add=0x0000: mac=00:00:01 hdlc_len=0x000

    GOOD :
    C_PrintExpected inline: terminal=0 list size=1
    BLAH::print add=0x0000: mac=23:24:25 hdlc_len=0x031
     
    hardwareman, Jun 28, 2005
    #1
    1. Advertising

  2. hardwareman

    Geo Guest

    hardwareman wrote:
    > Hi Folks,
    >
    > I can work around this problem, but it shows a problem in my
    > understanding of how things should work. Any ideas are appreciated.
    >
    > Thanks,
    > Hardwareman
    >
    > When the following subroutine is put inline the results are expected.
    > When the reference to the vector is passed, the reference has the
    > correct sizes but the 'Print' member function spews almost random junk.
    >
    > BLAH is an unordinary user class containing scalars.
    >
    > typedef vector<BLAH> EntryBram_T ;
    > typedef vector<EntryBram_T> Expected_T ;
    >
    > void C_PrintExpected ( Expected_T & expected ) {
    > for (int i=0 ; i < expected.size() ; i++) {
    > Msg(MSG_LOW, "%m: C_PrintExpected: terminal=%d list size=%d\n",
    > i, expected.size() ) ;
    > int j = 0 ;
    > // print out all expected entries
    > while (j < expected.size() ) {
    > (expected)[j].Print(j++) ;
    > }
    > }
    > }
    >
    >
    > The calling function:
    >
    > expected[ term ].push_back( EntryBram[original_start] ) ;
    > Msg(MSG_LOW, "%m: Print what we just pushed\n") ;
    > (expected[ term ].end()-1)->Print(original_start) ; // this is
    > fine
    > C_PrintExpected(expected) ; // THIS IS
    > WRONG
    >
    > // This inline code works as expected
    > for (int i=0 ; i < expected.size() ; i++) {
    > Msg(MSG_LOW, "%m: C_PrintExpected inline: terminal=%d list
    > size=%d\n",
    > i, expected.size() ) ;
    > int j = 0 ;
    > // print out all expected entries
    > while (j < expected.size() ) {
    > (expected)[j].Print(0) ;
    > j++ ;
    > }
    > }
    >
    > ////////////////
    > RUN RESULTS:
    >
    > BAD :
    > C_PrintExpected: terminal=0 list size=1
    > BLAH::print add=0x0000: mac=00:00:01 hdlc_len=0x000
    >
    > GOOD :
    > C_PrintExpected inline: terminal=0 list size=1
    > BLAH::print add=0x0000: mac=23:24:25 hdlc_len=0x031


    First off, the code in the function is not the same as the inlined
    code, however I'm not sure if the '.' in the line

    (expected)[j].Print(j++) ;

    counts as a sequence point, if not then you have UB, and therefore you
    should nothave any expectations of what should happen.
     
    Geo, Jun 28, 2005
    #2
    1. Advertising

  3. hardwareman

    Zara Guest

    -- non-inline--
    while (j < expected.size() ) {
    (expected)[j].Print(j++) ;

    doesn't work: because the argument to the function is evaluated before
    the object reference, so the first time it works like:
    (expected)[1].Print(0)
    ;

    -- inline --
    while (j < expected.size() ) {
    (expected)[j].Print(0) ;
    j++ ;
    }

    works ONLY the first time in the loop. Maybe it sould have been:
    while (j < expected.size() ) {
    (expected)[j].Print(j) ;
    j++ ;
    }
     
    Zara, Jun 28, 2005
    #3
  4. hardwareman

    hardwareman Guest

    Thanks for the sequence point note. You are right on. Seperating
    into:
    (expected)[j].Print(j) ;
    j++ ;

    corrects the problem.
    Thanks!
     
    hardwareman, Jun 28, 2005
    #4
  5. hardwareman

    Peter Julian Guest

    "hardwareman" <> wrote in message
    news:...
    > Hi Folks,
    >
    > I can work around this problem, but it shows a problem in my
    > understanding of how things should work. Any ideas are appreciated.
    >
    >

    <snip>

    nasty code. Why don't you reproduce compileable code with a
    std::vector< std::vector<int> > container?

    If you can't make it work with an int, it won't work with a Blaah.

    To use an iterator, you need to typedefine it (since containers, like
    vector, have their own predefined set of iterator types and in many cases,
    STL containers define their own specialized iterators).

    There are other ways of doing this, namely with algorithms. But that doesn't
    mean you can ignore iterators (thats what the algorithms use for the most
    part).

    #include <iostream>
    #include <vector>

    void Print( std::vector< std::vector<int> >& r_vv)
    {
    typedef std::vector< std::vector<int> >::iterator VVIter;
    VVIter it = r_vv.begin();

    for (it; it != r_vv.end(); ++it)
    {
    typedef std::vector<int>::iterator VIter;
    VIter niter = (*it).begin();
    for (niter; niter != (*it).end(); ++niter)
    {
    std::cout << *niter << " ";
    }
    std::cout << std::endl;
    }
    }

    int main()
    {
    std::vector< std::vector<int> > v_vn;

    for (int i = 0; i < 10; ++i)
    {
    std::vector<int> vn(10, i); // create container with 10 elements
    // having the value of i

    v_vn.push_back(vn); // push container into master container
    }

    Print(v_vn);

    return 0;
    }

    /*
    0 0 0 0 0 0 0 0 0 0
    1 1 1 1 1 1 1 1 1 1
    2 2 2 2 2 2 2 2 2 2
    3 3 3 3 3 3 3 3 3 3
    4 4 4 4 4 4 4 4 4 4
    5 5 5 5 5 5 5 5 5 5
    6 6 6 6 6 6 6 6 6 6
    7 7 7 7 7 7 7 7 7 7
    8 8 8 8 8 8 8 8 8 8
    9 9 9 9 9 9 9 9 9 9
    */
     
    Peter Julian, Jun 28, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. James Ash
    Replies:
    2
    Views:
    305
    James Ash
    Oct 20, 2003
  2. Replies:
    8
    Views:
    1,932
    Csaba
    Feb 18, 2006
  3. shuisheng
    Replies:
    8
    Views:
    377
    Jim Langston
    Sep 5, 2006
  4. minifish
    Replies:
    0
    Views:
    434
    minifish
    Oct 29, 2008
  5. Guest
    Replies:
    0
    Views:
    448
    Guest
    Sep 14, 2005
Loading...

Share This Page