ambercloud
ambercloud

Reputation: 21

How can I work around this circular dependency?

I'm making a sort of indexed list. I have a structure that looks something like this:

struct MyList {
    list<Word> records;
    map<char, list<list<Word>::iterator>> index;
    void add_word(Word);
    void erase_by_letter(char&);
};

Every time I add a Word to MyList, for every unique character it has I add an iterator on it into "index" map. This way I can quickly access every word that has a letter 'a' in it or letter 'n', etc. But this has an issue: after removing a Word from records every iterator pointing on it in index become invalid. To work around that every Word stores a list of references on it and ~Word() cleans them up on object removal. It looks something like this:

struct Word {
   Word(string);
   ~Word();
   vector<pair<list<list<Word>::iterator>*, list<list<Word>::iterator>::iterator>> refs;
   void add_ref(pair<list<list<Word>::iterator>*, list<list<Word>::iterator>::iterator>);
   void clean_refs();
   string value;
};

So. All of that works fine so far. To my rookie eye it doesn't look like a good design but I could live with that. The problem is GDB can't. I use VS Code + GDB and every time debugger comes anywhere near this structure it stops responding. My guess is it goes into an endless loop because an entry in index points to Word in records and Word itself has inside refs vector that points back to index entry and so on and on so poor debugger just stares into abyss.

Two questions:

  1. Can I make GDB to stop looking too deep into this loop or maybe detect it and give up on it?
  2. How should I implement this properly to avoid circular references?

Upvotes: 1

Views: 85

Answers (1)

Issylin
Issylin

Reputation: 565

Let's get back to the original problem : invalid iterators when a word is deleted.

First of all, I'd have removed all the reference stuff you have configured into your Word struct in order to get back to a clean state.

So now, we have this :

struct Word
{
   Word(string);
   ~Word();
   
   string value;
};

Now, let's go on your struct MyList. As you explained, the problem is the invalid iterators you have after deleting a word pointing at it.

Here is my proposal :

In the delete method you use to delete a word from MyList, before deleting the Word in question, 1. iterate over MyList and get the iterator pointing to your Word.

Then, 2. parse your map of iterators and delete the iterators which are the same than in step 1..

Finally, 3. delete your word From MyList.

Upvotes: 1

Related Questions