C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 08-14-2009, 08:08 AM   #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
ryanrigdon is offline   Reply With Quote
Old 08-14-2009, 08:20 AM   #2
The larch
 
Join Date: May 2006
Posts: 3,082
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.

Quote:
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).
anon is offline   Reply With Quote
Old 08-14-2009, 08:32 AM   #3
Registered User
 
Join Date: Jul 2009
Location: MD
Posts: 10
Thanks for the quick response anon. To answer your questions:
Quote:
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?
ryanrigdon is offline   Reply With Quote
Old 08-14-2009, 10:59 AM   #4
Registered User
 
Join Date: Jan 2005
Posts: 7,137
>> 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.
Daved is offline   Reply With Quote
Old 08-14-2009, 12:03 PM   #5
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,381
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.
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is offline   Reply With Quote
Old 08-14-2009, 12:14 PM   #6
Registered User
 
Join Date: Jul 2009
Posts: 32
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.
crowe is offline   Reply With Quote
Old 08-14-2009, 12:45 PM   #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.
ryanrigdon is offline   Reply With Quote
Old 08-14-2009, 01:06 PM   #8
Guest
 
Sebastiani's Avatar
 
Join Date: Aug 2001
Posts: 4,923
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.
Sebastiani is offline   Reply With Quote
Old 08-14-2009, 01:22 PM   #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.
ryanrigdon is offline   Reply With Quote
Old 08-14-2009, 01:29 PM   #10
Guest
 
Sebastiani's Avatar
 
Join Date: Aug 2001
Posts: 4,923
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?
Sebastiani is offline   Reply With Quote
Old 08-14-2009, 02:20 PM   #11
Algorithm Dissector
 
iMalc's Avatar
 
Join Date: Dec 2005
Location: New Zealand
Posts: 2,475
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
iMalc is offline   Reply With Quote
Old 08-14-2009, 06:52 PM   #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.
ryanrigdon is offline   Reply With Quote
Old 08-15-2009, 10:42 AM   #13
Registered User
 
Join Date: Jan 2005
Posts: 7,137
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.
Daved is offline   Reply With Quote
Old 08-17-2009, 01:13 PM   #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::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.
ryanrigdon is offline   Reply With Quote
Old 08-17-2009, 02:39 PM   #15
Registered User
 
Join Date: Sep 2004
Location: California
Posts: 2,845
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.
bithub is offline   Reply With Quote
Reply

Tags
c++, c++ 6, string, vector, visual c++

Thread Tools
Display Modes

Forum Jump

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


All times are GMT -6. The time now is 10:48 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22