0

Tratando de diagramar lo que sucede en la función "doIt" (está completa abajo) me encuentro con una duda puntual a la hora de realizar una comparación.

Duda: Luego de obtener el último nodo y asignarlo al puntero aux. Veo la siguiente comparación:

if(aux == lista)

Por un lado: ¿Compara aux -> info y lista -> info?¿Por qué estoy comparando?

Por el otro, luego de

aux = obtenerUltimo(lista);

¿el diagrama sería así?

introducir la descripción de la imagen aquí

Como comentario adicional "obtenerUltimo" retorna el último nodo de la lista. y la estructura del nodo sería:

struct Nodo
{
    int info;
    Nodo *sgte;
};

La función completa:

int doIt(Nodo *&lista)
{
    int elemento;
    Nodo *aux; Nodo *aux2;
    if(lista)
    {
        aux = obtenerUltimo(lista);
        if(aux == lista) // Duda
        {
            elemento = lista -> info;
            delete lista;
            lista = NULL;
            return elemento;
        }
        else
        {
            aux2 = lista;
            while(aux2->sgte != aux)
                aux2 = aux2->sgte;
            elemento = aux -> info;
            delete aux;
            aux -> sgte = NULL;
            return elemento;
        }
    }
    else
    {
        cout << "Error: vacia" << endl;
        return 0;
    }
}
jqc
  • 596
  • 8
  • 24
  • Esa función parece eliminar un nodo _(O varios, dependiendo)_, al hacer `aux == lista` verifica que sea el ultimo nodo para poder eliminarlo y devolver el valor de su respectivo `elemento`, por otra parte, si no se cumple esa condición, entonces solo itera la lista hasta llegar al elemento coincidente con `aux` _(El ultimo)_ y realiza la misma acción. Mi pregunta es: ¿Cuál es tu pregunta al respecto? – NaCl Feb 17 '18 at 02:09

1 Answers1

3

¿Compara aux -> info y lista -> info?

No.

¿Qué tipos son aux y lista?:

  • lista es una referencia a puntero a Nodo (Nodo *&lista).
  • aux es un puntero a Nodo (Nodo *aux).

A efectos prácticos una referencia se comporta igual que el tipo al que referencia, así que aux == lista está comparando dos punteros que no es más que comparar la dirección de memoria que contienen, no el contenido de aquello a lo que están apuntando.

En otras palabras, la expresión aux == lista será verdadera si tanto aux como lista están almacenando la misma dirección de memoria.

¿Por qué estoy comparando?

Tú sabrás, es tu código. Yo al leerlo no le veo mucho sentido, al menos debería tener sentido para ti que lo has desarrollado.

¿Tras obtener el último Nodo el diagrama sería así?

Suponiendo que obtenerUltimo haga lo que dices que hace: Si. Pero veamos qué sucede luego, primero supongamos que aux y lista apuntan al mismo Nodo:

En tu código, guardas elemento en una variable para devolverlo luego, borras el Nodo apuntado por lista, haces que apunte a NULL y devuelve elemento; tras estos pasos tu memoria quedaría parecida a esto:

Como puedes ver, el penúltimo Nodo se queda apuntando al Nodo borrado, asumo que esto será un problema pues dicho Nodo no ha sido informado de que su siguiente ha dejado de existir.

Cuando aux y lista no apuntan al mismo Nodo, haces avanzar otro puntero auxiliar (aux2) hasta quedarte en el nodo anterior a aux, seguidamente guardas elemento en una variable para devolverlo luego, borras el Nodo apuntado por aux, haces que (¡después de borrarlo!) su siguiente apunte a NULL y devuelves elemento. Este código fallará en tiempo de ejecución en la orden aux -> sgte = NULL;. Pero suponiendo que no fallase, partiendo de tu diagrama inicial, tras estos pasos tu memoria quedaría parecida a esto:

No sólo es erróneo por acceder a memoria borrada (delete aux; aux -> sgte = NULL;) si no que además el nodo que apunta aux2 tampoco ha sido informado de que su siguiente ha dejado de existir.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82