• Advertisement
Sign in to follow this  

STL Trouble and MSVC 2005

This topic is 4348 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey there, I'm having some trouble with the STL. I've got this dialog class that does some pretty lengthy calculations on many strings, and it's got a std::deque<string> namelist; container that has about ooo I say 100,000 elements in it. So when it's all finished, instead of calling namelist.clear(), which would freeze my app for several seconds, I run a message pump right before I close the dialog and pop_front (also tried erase(namelist.begin()) as well) the elements one-by-one so the app stays responsive. A progress control and status control text is used to show its progress. Now here's one problem: when the program is run from the IDE (in either Debug or Release mode), pop_front and erase don't seem to actually delete the memory associated with the element :O. Looking at the function _Tidy() -- called by Clear and the destructor of deque -- seems to confirm this as it pops the elements one-by-one and then deletes the map's memory). So even though I run a message pump, when my dialog class's destructor is called, my app freezes because _Tidy() is doing some major memory cleanup. Now here's the second problem: when the the program is run from outside the IDE (in either Debug or Release version), pop_front and erase actually seem to delete the memory associated with the element and my app doesn't hang when the dialog's destructor is called! Is there a way to delete the elements of a deque one-by-one without my app freezing? Why am I getting this inconsistant behavior when run inside/outside the IDE? If anyone wants a sample program of what I'm talking about, I'll post one as I can whip one up pretty fast. Thanks, Steve
class mpProgressDialog : public mpDialog {
 std::deque<std::string> namelist;
};

 // cleanup name list
 size_t elem = namelist.size();
 for(size_t i = 0; i < elem; i++)
    {
     namelist.pop_front(); // delete element
     mpForceWaitIdle(); // my dialog message pump

     // update progress bar and status display every 1/2 second
     update.EndClock();
     if(update.GetTimeElapsed() > 0.50) {
        update.BeginClock();
        thread.EndClock();
        char buffer1[256];
        int percent = (100*(i + 1))/(int)elem;
        sprintf_s(buffer1, 256, "Freeing name list... %ld%% done.", percent);
        double thread_time = (thread.GetTimeElapsed());
        double finish_time = (thread.GetTimeElapsed()*elem)/(i + 1) - thread.GetTimeElapsed();
        char buffer2[256];
        mpGetETRString(finish_time, buffer2, 256); // estimated time remaining
        mpSetWaitPercent((int)percent); // update progress bar
        mpSetWaitText1(buffer1); // update static controls
        mpSetWaitText2(buffer2);
       }
    }

Share this post


Link to post
Share on other sites
Advertisement
With that many std::string's there will always be a delay when destroying them all together because of all the small deallocations that need to be done (although note that the std::deque won't necessarily release it's memory with a call to clear()). Firstly, do you need to manipulate the names in any way? Is it possible that you could use char* instead? Also, using std::deque will result in a large number of smaller blocks being allocated instead of one big block for all 100,000 elements. Would std::vector with a call to reserve() be a viable option?

Ultimately, if you're sure your data types are correct I'd suggest the separate thread as well, but instead of calling namelist.clear() call namelist.swap(std::deque<std::string>()) so that it releases all the memory as well.

Share this post


Link to post
Share on other sites
ooo multithreading... that's definitely doable though i was looking into it today and i was wondering about custom allocators... can a custom allocator be used to ensure that a deque's capacity will always equal its size after popping/erasing elements? (Though it looks like in MSVC it's not possible because deque appears to use two allocators, one for the map and one for the values.)
Thanks

Share this post


Link to post
Share on other sites
You might write a custom allocator to speed up those allocations & deallocations.

Share this post


Link to post
Share on other sites
Quote:
Original post by yadango
ooo multithreading... that's definitely doable though i was looking into it today and i was wondering about custom allocators... can a custom allocator be used to ensure that a deque's capacity will always equal its size after popping/erasing elements? (Though it looks like in MSVC it's not possible because deque appears to use two allocators, one for the map and one for the values.)
Thanks


No, that's not possible. The allocator controls individual allocation/deallocation and construction/destruction but it doesn't control *when* those occur, that's up to the allocation strategy used by the std::deque implementation.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement