2010-07-26 10 views
5

Este es un seguimiento de una pregunta anterior que tuve (Complexity of STL max_element).elemento de borrado máximo del conjunto de STL

Quiero básicamente mostrar el elemento máximo de un conjunto, pero estoy teniendo problemas.

Aquí es más o menos mi código:

set<Object> objectSet; 

Object pop_max_element() { 
    Object obj = *objectSet.rbegin(); 
    set<Object>::iterator i = objectSet.end()--; //this seems terrible 
    objectSet.erase(i); //*** glibc detected *** free(): invalid pointer 
    return obj; 
} 

Antes he intentado objectSet.erase(objectSet.rbegin()); pero el compilador se quejaron de que no había ninguna función de emparejamiento (supongo que no le gusta el reverse_iterator). Sé que no hay ninguna comprobación de un conjunto vacío, pero está fallando cuando objectSet.size() >> 0.

+0

'* objectSet.rbegin();' ¿es un error tipográfico? estás desreferenciando el set? –

+1

No, es el iterador desreferenciado. El punto se une más apretado que la estrella. –

Respuesta

9

Estás bastante cerca, pero estás tratando de hacer demasiado en esa tarea del iterador. Está aplicando el operador post-decrement a lo que end devuelve. No estoy seguro de lo que hace eso, pero es casi seguro que no es lo que quieres. Asigne el resultado de end a i, y luego disminuya para obtener el último elemento del conjunto.

set<Object>::iterator i = objectSet.end(); 
--i; 
Object obj = *i; 
objectSet.erase(i); 
return obj; 
5

que tiene que hacer esto:

set<Object> objectSet; 

Object pop_max_element() { 
    Object obj = *objectSet.rbegin(); 
    set<Object>::iterator i = --objectSet.end(); // NOTE: Predecrement; not postdecrement. 
    objectSet.erase(i); //*** glibc detected *** free(): invalid pointer 
    return obj; 
} 
5

La declaración

set<Object>::iterator i = objectSet.end()--; 

significa 'final de asignación() para i luego DECREMENT una variable temporal que está a punto de ser lanzado lejos' . En otras palabras, es lo mismo que set<Object>::iterator i = objectSet.end();, y estoy seguro de que reconoce que no puede borrar end(), ya que apunta a uno pasado el final. Usar algo como esto en su lugar:

assert(!objectSet.empty()); // check there is something before end 
set<Object>::iterator i = objectSet.end(); 
--i; 
objectSet.erase(i); 

y eso está bien, es una forma legítima de reproducir esencialmente .back() para un conjunto.

Además, los iteradores inversos tienen un miembro base() para convertir a un iterador normal y supongo que solo puede borrar iteradores normales; intente objectSet.erase(objectSet.rbegin().base()).

+0

Probé el rbegin(). Base(), fue en vano. – sas4740

+3

'rbegin(). Base()' es lo mismo que 'end()'. –

Cuestiones relacionadas