Thread: Problems when destroying a vector of strings

  1. #1
    Registered User
    Join Date
    Jul 2009
    Location
    MD
    Posts
    10

    Unhappy Problems when destroying a vector of strings

    I have 2 vectors of strings. I'm passing them to a function by reference with one being const inside the function. I add some strings to the non-const vector and come out of the function. For some reason when the vector that was not const goes out of scope it throws exceptions when trying to deallocate the strings. Here is an example.
    Code:
    #include <vector>
    #include <string>
    using std::string;
    using std::vector;
    
    void func1(const vector<string> &vector1, vector<string> &vector2)
    {
    //it doesn't matter what happens to vector1 because it is working properly //disregard it for this example vector2.clear(); //to make sure it's empty //push on some random data for this example //I'm actually grabbing some text from an access DB for (int i = 0; i < 8; i++) {
    vector2.push_back("Go Time!");
    }
    } int main() {
    vector<string> vector1; vector<string> vector2; func1(vector1, vector2); //do something with vector 2 now, only reading from it though, no writing //I was letting them go out of scope but I couldn't tell which vector was having trouble //The problem manifests when clear() is called as well vector1. clear(); vector2.clear(); //here is where the program breaks return 1;
    }
    It doesn't seem matter what text is in the vector. I've tried rearranging the order of the string but it always seems to break on the second or third element. I've tried doing a pop_back() from the end of the vector and it goes fine until it gets up toward the beginning of the vector.

    Just for reference I'm using Visual C++ 6.0 (ugh) and vector1 destroys just fine. The actual exception is happening when in the std::string's deallocate function. It is throwing an assert on IsValidHeapPointer.

    Thanks in advance for any help.
    Last edited by ryanrigdon; 08-14-2009 at 08:25 AM. Reason: Just to remove a typo/programmer error

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    There isn't anything wrong here, except for void main, which should be int main(). Or does this exact example have the problem (if it runs fine why did you post it?)

    The cause of the problem may well be in the part that you consider irrelevant (such as going out of bounds). Or the compiler is horribly broken (hard to believe it is that broken).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User
    Join Date
    Jul 2009
    Location
    MD
    Posts
    10
    Thanks for the quick response anon. To answer your questions:
    Or does this exact example have the problem (if it runs fine why did you post it?)
    I posted this as an example of the operations I am performing on the vectors without bogging you down on the details. All I am doing is pushing some strings into the vector in func1 then reading them back from it after the func1 call.

    vector2 is never modified after coming out of func1.

    the exception always occurs when trying to deallocate the strings in vector2, whether by calling clear(), the vector going out of scope, or individually popping off each string.

    The only thing I forgot to mention is that in my code, func1 is in a dll. Could Is there any special consideration I'm not managing in regards to modifying a vector across a dll?

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Could Is there any special consideration I'm not managing in regards to modifying a vector across a dll?

    Make sure all your allocations and deallocations are done in the same module (see C++ Coding Standards item 60). I don't know if that's your problem, but I do know that there can be problems if you create your vector in one place and fill it in the dll. Something tells me this isn't your problem, but it's worth a shot to reserve space for the vector before sending it to the function. There still could be a problem with the string, though.

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by ryanrigdon View Post
    It is throwing an assert on IsValidHeapPointer.
    Heap stomping. The problem lies in the code you think is not relevant.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    Registered User
    Join Date
    Jul 2009
    Posts
    50
    Memory allocated in the DLL's heap is distinct from the executable's heap. This means that when you create memory inside the dll it must also be deleted inside the dll.

    This is especially a problem in your case as there's a lot of stuff going on inside the string constructor and it's highly likely that it's creating local pointers when you push to the vector in the dll and therefore errors out when you release that memory inside your main program.

    edit: I really like this term:
    Quote Originally Posted by brewbuck View Post
    Heap stomping.

  7. #7
    Registered User
    Join Date
    Jul 2009
    Location
    MD
    Posts
    10
    Code:
    #include <vector>
    #include <string>
    using std::string;
    using std::vector;
    
    //func1 is in a separate dll
    void func1(const vector<string> &vector1, vector<string> &vector2)
    {
    //it doesn't matter what happens to vector1 because it is working properly //disregard it for this example //assign new values to the initialized strings for (int i = 0; i < 8; i++) {
    vector2[i] = "Go Time!";
    }
    } int main() {
    vector<string> vector1; vector<string> vector2(20, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); func1(vector1, vector2); //I was letting them go out of scope but I couldn't tell which vector was having trouble //The problem manifests when clear() is called as well vector1. clear(); vector2.clear(); //here is where the program breaks return 1;
    }
    Even though I'm not allocating anything in the dll and not doing anything with the vector after getting it back I'm still getting an assert from IsValidHeapPointer in std::string's destructor. But if I take out the call to func1 it works just fine.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by brewbuck View Post
    Heap stomping. The problem lies in the code you think is not relevant.
    Yep, nice choice of words there. =)

    >> Even though I'm not allocating anything in the dll and not doing anything with the vector after getting it back I'm still getting an assert from IsValidHeapPointer in std::string's destructor. But if I take out the call to func1 it works just fine.

    Well, in the code you posted you aren't checking the bounds of vector - try constraining it to vector2.size( ) and recheck.

  9. #9
    Registered User
    Join Date
    Jul 2009
    Location
    MD
    Posts
    10
    I'm not sure where you mean for me to check the bounds unless it is in the "for" loop in func1. Unfortunately, checking the bounds isn't going to help because the error occurs in clear() which requires no bounds checking. I have even tried
    Code:
    for (int i = 0; i < vector2.size(); i++)
    {
    
    vector2.pop_back();
    }
    This makes it all the way up to the second or third element and then breaks with the same error.

  10. #10
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by ryanrigdon View Post
    I'm not sure where you mean for me to check the bounds unless it is in the "for" loop in func1. Unfortunately, checking the bounds isn't going to help because the error occurs in clear() which requires no bounds checking. I have even tried
    Code:
    for (int i = 0; i < vector2.size(); i++)
    {
    vector2.pop_back();
    }
    This makes it all the way up to the second or third element and then breaks with the same error.
    Can you provide a sample project file that that compiles?

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by ryanrigdon View Post
    I posted this as an example of the operations I am performing on the vectors without bogging you down on the details.
    Sadly, the only thing that is going to be of use for us to help solve the problem is the details.
    Otherwise it's like finding a picture of a car engine on the net to post on a forum and say, "see my car has broken down".

    My advice is that where a call to a different module is involved (e.g. EXE to DLL) DO NOT pass or return standard library structures of any kind. Maybe you will get away with it if it is const and both are built using the same project setting every time, but in general don't do it.
    Find another way such as passing a callback function pointer into the DLL that you call to add an item to the collection, and perhaps one you can call to access an item, and another you can call to clear the container, or something like that.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Registered User
    Join Date
    Jul 2009
    Location
    MD
    Posts
    10
    Unfortunately simplifying my production code to do exactly what is shown in my last example func1 still has issues. I stripped everything else out of it and I'm still having deallocation issues. I don't have Visual Studio 6 at home so I won't be able to create a sample project this weekend but I'll make one when I get back to work on Monday. If anyone has a suggestion of another way to do this it would be welcomed with open arms. Thanks for all of your help so far.

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Sorry for not reading the entire thread since the last time I checked in, but if you're assigning new strings in the dll and the vector is destroyed in the main codeline, then that will still be the same problem (strings allocate memory).

    If you really wanted to verify that this isn't the problem, and you know the maximum size of your strings, try something like this:
    Code:
    const unsigned max_vec_size = 100; // or whatever
    const unsigned max_string_size = 100; // or whatever
    std::vector<std::string> my_vec(max_vec_size, std::string (max_string_size, '\0'));
    
    my_func_in_dll(my_vec);
    Hopefully that will avoid any string allocations in the dll.

  14. #14
    Registered User
    Join Date
    Jul 2009
    Location
    MD
    Posts
    10
    Ok, so I found the solution to my problem. I was doing everything correctly except that I'm using an old microsoft product. This was in an obscure MS KB article STL std&#58;&#58;string class causes crashes and memory corruption on multi-processor machines.

    Long story short: the entire STL that shipped with VC++ 6 is not thread-safe, especially std:: string. Thanks for all of your help and sorry for the confusion.

  15. #15
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Quote Originally Posted by ryanrigdon View Post
    Ok, so I found the solution to my problem. I was doing everything correctly except that I'm using an old microsoft product. This was in an obscure MS KB article STL std::string class causes crashes and memory corruption on multi-processor machines.

    Long story short: the entire STL that shipped with VC++ 6 is not thread-safe, especially std:: string. Thanks for all of your help and sorry for the confusion.
    It's worse than that. The STL that shipped with VC++ 6 was written before the C++ standard, so it has a rather poor implementation. There are all kinds bugs and inconsistencies with that STL implementation. There are some service packs for VC6 that fix a lot of compiler bugs which (I think) bring it pretty close to a correct implementation of the C++ standard.
    bit∙hub [bit-huhb] n. A source and destination for information.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. String problems - strings seem to join?
    By Metalixia in forum C++ Programming
    Replies: 2
    Last Post: 01-18-2007, 11:00 AM
  2. strings in C++
    By elad in forum C++ Programming
    Replies: 11
    Last Post: 05-20-2006, 02:27 AM
  3. Problems with strings as key in STL maps
    By all_names_taken in forum C++ Programming
    Replies: 3
    Last Post: 01-17-2006, 11:34 AM
  4. Getting the number of strings in a STRINGTABLE resource
    By eth0 in forum Windows Programming
    Replies: 1
    Last Post: 09-30-2005, 02:57 AM
  5. Reading strings input by the user...
    By Cmuppet in forum C Programming
    Replies: 13
    Last Post: 07-21-2004, 06:37 AM

Tags for this Thread