问题
The goal of my test program is to erase a cell in a simple vector of strings like below. The program fail (segmentation fault).
static void display(std::vector<std::string> const &vec)
{
std::vector<std::string>::const_iterator It = vec.begin();
for (; It != vec.end(); ++It)
std::cout << *It << " ";
std::cout << std::endl;
}
int main(void)
{
std::vector<std::string> vec;
size_t index = 0;
vec.push_back("Toto");
vec.push_back("Titi");
vec.push_back("Tata");
vec.push_back("Tutu");
display(vec);
std::vector<std::string>::iterator It = vec.begin();
for (size_t idx = 0; It != vec.end(); ++It, idx++)
if (!(*It).compare("Tutu"))
index = idx;
vec.erase(std::remove(vec.begin(), vec.end(), index), vec.end()); //Segmentation fault
display(vec);
getchar();
return (0);
}
Does anyone can help me? Thanks in advance for your help.
回答1:
vec.erase(std::remove(vec.begin(), vec.end(), index), vec.end());
You need to pass the actual element (in this case of type std::string
) to your erase
function.
So instead of index
, it should be somestring
回答2:
- you shall not mix iterators and homebrew indices. use the iterators only.
algorithms like copy - there are external algorithms for use when you want to decouple from the actual container type and there are member functions that do an optimized job. in your case vec erase does everhting for you, just pass the found iterator
vec.erase(It);
回答3:
Since you're checking for equality, just use std::remove
:
vec.erase( std::remove( vec.begin(), vec.end(), "Tutu" ),
vec.end() );
It's the standard idiom. If for some reason, you have to write the loop yourself:
std::vector<std::string>::const_iterator current = vec.begin();
while ( current != vec.end() ) {
if ( *current == "Tutu" ) {
current = vec.erase( current ) ;
} else {
++ current;
}
}
(Again, the standard idiom.)
来源:https://stackoverflow.com/questions/13661355/stdremove-does-not-work