CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 23
  1. #1
    Join Date
    Mar 2010
    Posts
    16

    Selfappending vector

    Hello,

    I've got a strange problem:

    #include <vector>
    #include <iostream>
    #include <string>

    int main(){
    std::vector<std::string> strvec;
    strvec.push_back("A");
    strvec.push_back("B");
    strvec.push_back("C");
    strvec.push_back("D");
    strvec.push_back("E");

    std::vector<std::string>::size_type i = strvec.size()-1;
    for(;i>0;--i)
    strvec.push_back(strvec[i-1]);

    for each(std::string str in strvec)
    std::cout << str << ',';

    return 0;
    }

    Gives me;
    A,B,C,D,E,D,,B,A

    What am I doing wrong?

  2. #2
    Join Date
    Mar 2010
    Location
    Aalten, Holland
    Posts
    14

    Re: Selfappending vector

    You have a vector containing only std::strings and you asked to get every std::string out of strvec here
    Code:
     for each(std::string str in strvec)
    std::cout << str << ',';
    That is what you are doing wrong. What do you exactly want to do?

  3. #3
    Join Date
    Mar 2010
    Posts
    16

    Re: Selfappending vector

    Thats even stranger. The origenal program is longer than this example.
    In the original A,B,C and D are "real" strings.
    A for example is X10, B is pauze, C is Y20, D is pauze and E is X-20.

    In my program I would like the resulting vector to contian;
    ("X10","pauze","Y20","pauze","X-20","pauze","Y20","pauze","X10")

    But the resulting vector in my program contains;
    ("X10","pauze","Y20","pauze","X-20","pauze","","pauze","X10")

    Thanks for the fast reply, btw.

  4. #4
    Join Date
    Mar 2010
    Location
    Aalten, Holland
    Posts
    14

    Re: Selfappending vector

    Give me a second, ill try to fix it myself first then explain it to you.

    Well, the output at me is
    Quote Originally Posted by Output
    A,B,C,D,E,D,C,B,A
    o_o.

  5. #5
    Join Date
    Mar 2010
    Posts
    16

    Re: Selfappending vector

    Nope, keep having this problem. Maybe it's my intel atom, or it's because I'm using visual studio 2008.

    However...

    for(;i>0;--i){
    std::string str = strvec[i-1];
    strvec.push_back(str);
    }

    works.

    Thank you very much.

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

    Re: Selfappending vector

    Quote Originally Posted by po0ky View Post
    for each(std::string str in strvec)
    std::cout << str << ',';

    return 0;
    }

    Gives me;
    A,B,C,D,E,D,,B,A

    What am I doing wrong?
    Use your debugger. What does the vector actually contain? Does it have the items?

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Mar 2010
    Posts
    16

    Re: Selfappending vector

    No, according to the debugger the vector holds all the items the cout is giving me.

    Pynolathgeen seems to get the expected results.
    Thats why I think its a bug in my compiler.

    @Pynolathgeen what compiler are you using?

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

    Re: Selfappending vector

    Quote Originally Posted by po0ky View Post
    No, according to the debugger the vector holds all the items the cout is giving me.

    Pynolathgeen seems to get the expected results.
    Thats why I think its a bug in my compiler.
    I don't think it's a bug in the compiler at all. Take a look at this line of code carefully:
    Code:
    strvec.push_back(strvec[i-1]);
    Do you see the problem with this line of code? The problem is that you're modifying the vector that you're reading from. The push_back() takes a reference to the item to add. You are giving a reference, but at the same time, you're changing the container that gives you that reference. Therefore the behaviour is undefined.

    For example, what if adding an item causes a reallocation to occur? That reference you passed is no longer valid, and I have a suspicion this is the reason why your code didn't work -- a reallocation was done, the reference is refering to junk, and you get a blank that is added.

    So the bottom line is that there is no such thing as a "self-appending vector" in the sense that you can't call push_back() with a reference to one of the vector's items.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; March 28th, 2010 at 09:49 PM.

  9. #9
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Selfappending vector

    Quote Originally Posted by Paul McKenzie
    Do you see the problem with this line of code? The problem is that you're modifying the vector that you're reading from. The push_back() takes a reference to the item to add. You are giving a reference, but at the same time, you're changing the container that gives you that reference. Therefore the behaviour is undefined.

    For example, what if adding an item causes a reallocation to occur? That reference you passed is no longer valid, and I have a suspicion this is the reason why your code didn't work -- a reallocation was done, the reference is refering to junk, and you get a blank that is added.

    So the bottom line is that there is no such thing as a "self-appending vector" in the sense that you can't call push_back() with a reference to one of the vector's items.
    Good point, though it seems to me that the conclusion is rather pessimistic. Wouldn't this be okay?
    Code:
    strvec.push_back(string(strvec[i - 1]));
    But taking another look at the problem, it seems that the aim is to insert to the same vector the elements of the vector starting from the second last element to the first element. Keeping in mind that reallocation could be a problem, would this solution be feasible?
    Code:
    strvec.reserve(strvec.size() * 2 - 1);
    strvec.insert(strvec.end(), strvec.rbegin() + 1, strvec.rend());
    As long as strvec has at least one element, I think that the above snippet should work.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  10. #10
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Selfappending vector

    Quote Originally Posted by laserlight View Post
    Good point, though it seems to me that the conclusion is rather pessimistic. Wouldn't this be okay?
    This should work.
    You use the reference to create a temporary string object (safe)
    You use the temporary string object to add to a vector (safe)
    the fact it's the same vector in this case isn't a problem anymore. At the moment you do the add, the reference used to create the temporary string will be invalid, but you have made a copy of the contents.

    would this solution be feasible?
    Code:
    strvec.reserve(strvec.size() * 2 - 1);
    strvec.insert(strvec.end(), strvec.rbegin() + 1, strvec.rend());
    It will probably appear to work. But I'm not sure it's guaranteed (but my experience with stl isn't perfect).
    if I read the documentation for reserve(), it would appear it's valid to implement this by making sure you have the required storage (by allocating a new location for the aray), but not actually copy the array to the new location until necessary.

  11. #11
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725

    Re: Selfappending vector

    In practice, I think the reserve method will work, however ...

    Concening the last 2 arguments, according the standard, the
    pre condition for the last two arguments is that they are not
    iterators into the vector (Table 67)

  12. #12
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Selfappending vector

    Indeed. So, does the motivation behind that pre-condition also invalidate the use of std::copy with std::back_inserter?
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  13. #13
    Join Date
    Mar 2010
    Posts
    16

    Re: Selfappending vector

    There I go blaming the compiler again. Thanks Paul McKenzie I think I understand the problem better now.

    Quote Originally Posted by laserlight View Post
    Good point, though it seems to me that the conclusion is rather pessimistic. Wouldn't this be okay?
    Code:
    strvec.push_back(string(strvec[i - 1]));
    I think this would be a good solution, if not the only solution.
    I'll try it right away.

  14. #14
    Join Date
    Oct 2002
    Location
    Timisoara, Romania
    Posts
    14,360

    Re: Selfappending vector

    You could also do this using a second, temporary vector:
    Code:
       vector<string> vec, temp;
       vec.push_back("A");
       vec.push_back("B");
       vec.push_back("C");
       vec.push_back("D");
       vec.push_back("E");
       copy(vec.rbegin()+1, vec.rend(), back_inserter(temp));
       vec.insert(vec.end(), temp.begin(), temp.end());
    
       copy(vec.begin(), vec.end(), ostream_iterator<string>(cout, " "));
    Output is
    Code:
    A B C D E D C B A
    Marius Bancila
    Home Page
    My CodeGuru articles

    I do not offer technical support via PM or e-mail. Please use vbBulletin codes.

  15. #15
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Selfappending vector

    Quote Originally Posted by cilu
    You could also do this using a second, temporary vector:
    If you want to involve a second vector, then I suggest declaring temp near first use:
    Code:
    vector<string> vec;
    vec.push_back("A");
    vec.push_back("B");
    vec.push_back("C");
    vec.push_back("D");
    vec.push_back("E");
    
    vector<string> temp(vec.rbegin() + 1, vec.rend());
    vec.insert(vec.end(), temp.begin(), temp.end());
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

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