-1

I have a segmentation fault I can't understand. This is the code:

void RemoveDuplicates(list<int>& _list)
{
    set<int> uniqueElements;
    list<int>::iterator iter = _list.begin();
    list<int>::iterator next;
    pair<set<int>::iterator, bool> res;

    while (iter != _list.end())
    {
        res = uniqueElements.insert(*iter);
        if (!res.second)
        {
            next = ++iter;
            _list.erase(iter);
            iter = next;
            continue;
        }
        iter++;
    }
}

and a test for the function (in a separate file):

#include <list>
#include <iostream>
#include "lists.h"

using namespace std;

int main()
{
    list<int> list;
    list.push_front(12);
    list.push_front(7);
    list.push_front(2);
    list.push_front(9);
    list.push_front(12);
    list.push_front(12);
    list.push_front(19);

    RemoveDuplicates(list);
    cout << list.size() << endl;

    return 0;
}

The segmentation fault occurs at curtain iteration of the while loop that looks quite random to me. When accessing the 5th element in the list (the one with the value 2) in the following line:

res = uniqueElements.insert(*iter);

The problem is accessing *iter. When I run it through gdb (on g++), I print the *iter each loop (gdb shows the address of the element and its value), and then when I get to the 5th one, it says 'error reading variable'.

As for the duplicate I think I understand the logic of removing a node from a list, but I still have the problem. The ++iter was changed from iter++ (probably wrongly) as an attempt to solve the problem. I changed it back to

next = iter++;

and I am getting the following error: invalid pointer program received signal SIGABRT, Aborted

Hana
  • 535
  • 2
  • 7
  • 17

1 Answers1

0
        next = ++iter;

iter is incremented, then assigned to next. Both next and iter now point to the element following the one you want to remove, or past the last element of the list.

        _list.erase(iter);

The (wrong) element, if any, is erased, invalidating both next and iter. If unlucky, you try to erase the end iterator.

        iter = next;

A no-op. They were pointing to the same element, and invalidated together.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243