C++ Error al borrar última casilla de un vector con iteradores

Iniciado por Orubatosu, 3 Diciembre 2014, 17:22 PM

0 Miembros y 1 Visitante están viendo este tema.

Orubatosu

Ahaha... claro como el agua.

Da gusto cuando las cosas al final no solo funcionan, sino que además sabes porque lo hacen  ;-)
"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998

Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Orubatosu

Vale... ahora he entendido realmente porque hay que usar el método de igualar.

Lo pongo para los que se encuentren con este problema, porque el motivo es cuando menos... "curioso" y si a mi me ha pasado, supongo que les pasará a mas personas.

El caso que tenía:


int main() {
    vector<int> A = {1, 2, 3, 4, 5, 6, 7, 8};
    vector<int>::iterator it = A.begin();
    cout << *it;
    A.erase(it);
    cout << *it;
}


Funciona, pero no es correcto


int main() {
    vector<int> A = {1, 2, 3, 4, 5, 6, 7, 8};
    vector<int>::iterator it = A.begin();
    cout << *it;
    it = A.erase(it);
    cout << *it;
}


Así es correcto.

El motivo (que tiene cojones) es que el iterador en realidad apunta a una posición de memoria. Esto puede parecer algo irrelevante, ya que para nosotros el iterador apunta a una casilla del vector.

Pero... ah... pero el sistema puede mover el vector de unas posiciones de memoria a otras sin avisarnos para optimizar el uso de la memoria. En operaciones de borrado por lo general no debería de haber problemas, pero cuando insertamos en lugar de borrar, el vector aumenta de tamaño, al aumentar de tamaño ocupa mas memoria y si no puede hacerse mas grande en la posición en la que se encuentra, porque los bloques contiguos están ocupados por otras variables (o por lo que sea), el sistema mueve todo el vector a otras posiciónes de memoria.

Y claro, mueve el vector... pero el iterador se queda "mirando para Cuenca" por decirlo de algún modo. Se queda apuntando a una posición de memoria donde el vector puede ya no estar.

Haciendo estas operaciones como asignaciones, los métodos de insert y erase devuelven un iterador que siempre apunta al vector resultante . Se mueva o no el vector en la memoria.

Y yo que creía que lo había entendido... pero solo a medias  ;D
"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998

Eternal Idol

Si, por eso lo de:
Cita de: Eternal Idol en  3 Diciembre 2014, 20:03 PM
Me parece que no hay ninguna garantia de que it continue siendo valido despues de llamar a erase

En el enlace que dejaste al principio lo deja claro:
Iterator validity
Iterators, pointers and references pointing to position (or first) and beyond are invalidated, with all iterators, pointers and references to elements before position (or first) are guaranteed to keep referring to the same elements they were referring to before the call.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón