Thread: STL Set erase()

  1. #1
    Registered User
    Join Date
    Feb 2003
    Posts
    596

    STL Set erase()

    I have
    vector<set<unsigned short>> theVector
    vector<set<unsigned short>>::iterator vecIter
    and
    set<unsigned short> *theSetP

    I use
    theSetP = new set<unsigned short>()
    to create various sets,
    theVector.push_back(*theSetP)
    to insert them into the vector,
    and when I'm finished with one of them I use
    theVector.erase(vecIter)
    to delete it.

    Does this completely delete the set and free its memory space, or should I be doing this differently?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Yes, but that is because
    Code:
    theVector.push_back(*theSetP);
    makes a copy of the set.

    You still need to delete theSetP, so you might want to consider not doing it this way at all.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    That's a lesson for me. So, in the definition
    Code:
    void push_back( const TYPE& val );
    does the "const" indicate that push_back is making its own copy of the set?

    So every time I reuse my pointer to create a new set, I'm losing the memory that the previous one occupied?

    So, should I delete each set after pushing it onto the vector, or is there a better way?

    And what's the best way to delete all sets remaining in the vector before the program returns? Is
    theVector.clear()
    adequate for that?
    Last edited by R.Stiltskin; 03-26-2007 at 09:17 PM.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    does the "const" indicate that push_back is making its own copy of the set?
    Standard containers can only store objects that have normal copying semantics, and it is known that they store a copy of what is passed to them.

    So, should I delete each set after pushing it onto the vector, or is there a better way?
    That is one way, but better yet if it is possible: do not even use a pointer, and simply create the set as you pass it to the vector. If you are inserting n empty sets at the start, then you can just write:
    Code:
    vector<set<unsigned short> > theVector(n);
    From there any changes to the sets can be done via an iterator to the vector, by using theVector[x], etc.

    And what's the best way to delete all sets remaining in the vector before the program returns?
    The vector will handle its own memory management. This will suffice here since your vectors are vectors of set objects, not of pointers to set objects (in which case you have to decide if the pointer in the vector or the pointer outside has ownership of the object).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Quote Originally Posted by laserlight View Post
    That is one way, but better yet if it is possible: do not even use a pointer, and simply create the set as you pass it to the vector. If you are inserting n empty sets at the start, then you can just write:
    Code:
    vector<set<unsigned short> > theVector(n);
    I can't do that. The number of sets is only determined at runtime, so I guess I'll just have to do new and delete for each one.

    Thanks for clueing me in on what "is known" about what STL containers store. It wasn't known by me.

  6. #6
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    > The number of sets is only determined at runtime, so I guess I'll just have to do new and delete for each one

    As far as I can tell, that's no reason to dynamically allocate each set. You can push_back (virtually) as many sets as you want, regardless of whether they're allocated with new or not.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Besides the fact that you don't have to dynamically allocate each set, laserlight's solution still works even if the number of sets isn't known until runtime. As long as you know how many sets there will be before execution reaches the part of code that initializes the vector, you can construct it or resize it to hold the correct amount of empty sets.

    Some examples of options:
    Code:
    std::vector<std::set<int> > theVector;
    while (haveMoreSets)
    {
        std::set<int> theSet;
        // fill theSet with data
        theVector.push_back(theSet);
        // Set haveMoreSets to true or false
    }
    Code:
    std::vector<std::set<int> > theVector;
    while (haveMoreSets)
    {
        theVector.push_back(std::set<int>());
        std::set<int>& theSet = theVector.back(); // notice the reference
        // fill theSet with data
        // Set haveMoreSets to true or false
    }
    Code:
    std::cin >> numberOfSets;
    std::vector<std::set<int> > theVector(numberOfSets);
    for (size_t i = 0; i < numberOfSets; ++i)
    {
        // fill theVector[i] with data
    }

  8. #8
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Quote Originally Posted by Daved View Post
    Besides the fact that you don't have to dynamically allocate each set, laserlight's solution still works even if the number of sets isn't known until runtime. As long as you know how many sets there will be before execution reaches the part of code that initializes the vector, you can construct it or resize it to hold the correct amount of empty sets.
    I guess "at runtime" didn't describe my application correctly. The vector is created when the function is called. Then, as the function runs, sets are being created, merged, deleted, additional sets created, and so on, until all the data is processed, and there is no way to determine at the beginning how many sets there will be. I don't know how many sets are used until the function finishes. So it seemed that the most efficient way to handle this was by dynamically allocating them. Isn't this exactly the purpose of dynamic allocation?

  9. #9
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    So it seemed that the most efficient way to handle this was by dynamically allocating them.
    Vector is already a dynamic container, no need to use new/delete directly to dynamicaly change its size
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  10. #10
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Quote Originally Posted by vart View Post
    Vector is already a dynamic container, no need to use new/delete directly to dynamicaly change its size
    Who said anything about using new/delete to change its size?

    The vector may be dynamic, but it's not so dynamic that it gives birth to sets.

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    have you read this code sample provided by Daved?
    Code:
    std::vector<std::set<int> > theVector;
    while (haveMoreSets)
    {
        std::set<int> theSet;
        // fill theSet with data
        theVector.push_back(theSet);
        // Set haveMoreSets to true or false
    }
    or this
    Code:
    while (haveMoreSets)
    {
        theVector.push_back(std::set<int>());
        std::set<int>& theSet = theVector.back(); // notice the reference
        // fill theSet with data
        // Set haveMoreSets to true or false
    }
    both dynamically "birth" sets without using new
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Oops, sorry, I guess I wasn't quite awake yet.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. optimising program
    By SONU in forum C Programming
    Replies: 1
    Last Post: 05-18-2008, 10:28 AM
  2. Set STL
    By DarkDot in forum C++ Programming
    Replies: 5
    Last Post: 05-02-2007, 02:58 PM
  3. 6 measly errors
    By beene in forum Game Programming
    Replies: 11
    Last Post: 11-14-2006, 11:06 AM
  4. The new FAQ
    By Hammer in forum A Brief History of Cprogramming.com
    Replies: 34
    Last Post: 08-30-2006, 10:05 AM
  5. OpenGL Window
    By Morgul in forum Game Programming
    Replies: 1
    Last Post: 05-15-2005, 12:34 PM