Question

A few days ago I asked for help in removing a value from a vector by value instead of it's index, see thread here ( How to overload '==' operator within a struct? )

I was able to get a solution to compile thanks to the help of Angew, the solution is marked as 'answered' in the thread.

However, when executing my program with this fix, my program halts unexpectedly, and when running it through a debugger, it seems that the fix caused a memory leak, could anyone provide insight about how this could occur?

Once again, here is my struct that I use to find the value I'm trying to remove:

struct IsUnderScore{
bool operator()(char c){
    return c=='_';
}
};

I can use it on a string using the erase-remove idiom very easily like so:

string.erase(remove_if(string.begin(), string.end(), IsUnderScore()), string.end());

but when using it on a vector I had compiler issues which were solved like so:

vector.erase(std::remove(vector.begin(), vector.end(), std::string("_")));

And now I get a memory leak.

EDIT: Here is a copy of the error given by gdb.

Program received signal SIGSEGV, Segmentation fault.
0x00002aaaab917ee8 in std::string::_Rep::_M_is_leaked ()
Was it helpful?

Solution

This code has a potential problem:

vector.erase(std::remove(vector.begin(), vector.end(), std::string("_")));

If the std::remove doesn't match any elements it returns vector.end(). Erasing an end() iterator is undefined behavior and a segfault can be the result.

I think you want the two-argument overload of std::vector::erase since it can handle an empty range. It's also the correct thing to do in case std::remove matches multiple elements...

vector.erase(std::remove(vector.begin(), vector.end(), std::string("_")), vector.end());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top