0

I am trying to remove a string from the vector if the string is equal to the original word provided so the output does not count the inputed word as an anagram of it self (if that makes sense)

for (std::vector<std::string>::const_iterator word = anagrams.begin();
       word != anagrams.end(); ++word) {
    if (*word != originalstring) {
      ++totalNumber;
      // std::cout << *i;
    } else {
      anagrams.erase(word);
    }
  }

really unsure why I am getting this error as it should be erasing the original word but I get the segmentation error :/

ジルビズ
  • 61
  • 2
  • 4
  • 2
    [Invalidates iterators and references at or after the point of the erase, including the end() iterator.](https://en.cppreference.com/w/cpp/container/vector/erase) – tkausl Mar 04 '19 at 00:20

1 Answers1

0

std::vector::erase

Invalidates iterators and references at or after the point of the erase, including the end() iterator.

Return value Iterator following the last removed element. If the iterator pos refers to the last element, the end() iterator is returned.

You need to alter your iterator increment just slightly to account for the iterator being invalidated after you erase.

for (std::vector<std::string>::const_iterator word = anagrams.begin();
       word != anagrams.end();) {
    if (*word != originalstring) {
      ++totalNumber;
      ++word;
      // std::cout << *i;
    } else {
      word = anagrams.erase(word);
    }
  }

As pointed out by by tkasul, using the std algorithms here would certainly be a cleaner solution:

anagrams.erase(std::remove(anagrams.begin(), anagrams.end(), originalstring), anagrams.end());
totalNumber = anagrams.size();
tkausl
  • 13,686
  • 2
  • 33
  • 50
tinkertime
  • 2,972
  • 4
  • 30
  • 45
  • A remove-erase would be a cleaner solution though. – tkausl Mar 04 '19 at 00:32
  • Wonderful thank you so much :) it works perfectly – ジルビズ Mar 04 '19 at 00:33
  • and whats a remove erase? – ジルビズ Mar 04 '19 at 00:33
  • I suspect that's what you were suggesting tkausl? Certainly don't suggest using code the OP isn't familiar with though :) – tinkertime Mar 04 '19 at 00:36
  • Yeah i am not really familier with it but I would like to learn and understand it. I understand everything apart from this and also within the return I am getting originalstring cannot be implicily captured in a lambda with no capture-default – ジルビズ Mar 04 '19 at 00:39
  • i captured `this` assuming `originalstring` was a member of the local scoped obj, but if `originalstring` is just a local variable then put that in the capture list (as a reference) – tinkertime Mar 04 '19 at 00:43
  • I have it set like this [originalword]() etc... kept the rest the same however, it does not remove the element using that method unfortunnantly ;? – ジルビズ Mar 04 '19 at 00:46
  • @ジルビズ @tinkertime missed the important erase-step. `std::remove` doesn't really remove anything, it merely _moves_ all to-be-removed objects to the end of the sequence and returns an iterator to the first to-be-removed object. Erase then takes this iterator and the end-iterator and does all deletions at once, very efficiently as the objects are already all at the end of the sequence. Note that you don't need `std::remove_if` in your example, `std::remove` tests for equality the same way you did manually in your lambda. – tkausl Mar 04 '19 at 08:30