Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

I don't understand why my sort on a string breaks everything

I have the following code:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>

using namespace std;

vector<vector<string>> findAnagrams(vector<string> wordlist) {
  vector<vector<string>> result;
  unordered_map<string, vector<string>*> indexes;

  for (const string& word : wordlist) {
    string wordSorted = word;
    sort(wordSorted.begin(), wordSorted.end()); // <= This line break everything

    auto index = indexes.find(wordSorted);
    if (index == indexes.end()) {
      vector<string> vec = { word };
      result.push_back(vec);
      indexes[wordSorted] = &vec;
    } else {
      index->second->push_back(word);
    }
  }

  return result;
}

int main()
{
    vector<string> wordlist = {"eat", "tea", "tan", "ate", "nat", "bat", "test", "estt"};
    auto result = findAnagrams(wordlist);

    for (const auto& vec : result) {
      for (const auto& word : vec) {
        cout << word << " ";
      }
      cout << endl;
    }

    return 0;
}

This code detects all anagrams in a list of given words.

As my comment says, when I sort wordSorted using std::sort, it breaks everything and my code ends with a bad_alloc. As if the std::sort manipulates the memory outside of wordSorted. If I remove this specific line, the code "works" (the result is obviously wrong, but it does what it should do).

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

How it is possible? What am I missing?

>Solution :

I’m guessing these lines are the main cause of your problem:

{
    vector<string> vec = { word };
    result.push_back(vec);
    indexes[wordSorted] = &vec;
}

Here you store a pointer to the local variable vec in the indexes map. When the block ends at } the life-time of vec also ends, and the pointer you just stored will become invalid.

Any use of this pointer will lead to undefined behavior.

It seems to me that the solution is to simply not store pointers to the vector (pointers to containers are seldom, if ever, needed), and instead store a copy.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading