Error doing delete C ++

1

I have something very simple in C ++ (trying to remember it) a library that I call element.h:

using namespace std;

typedef struct elemento{
       int clave;
       string nombre;
       string apellido;
       struct elemento *prox;
}Elemento;


Elemento crearElemento(int clave, string nombre, string apellido){
    Elemento e;
    e.clave    = clave;
    e.nombre   = nombre;
    e.apellido = apellido;
    e.prox = NULL;
    return e;
}

void imprimirElemento(Elemento e){
    cout << "-----------------------------------------------" << endl;
    cout << "CLAVE    =" << e.clave << endl;
    cout << "NOMBRE   =" << e.nombre << endl;
    cout << "APELLIDO =" << e.apellido << endl; 
    cout << "-----------------------------------------------" << endl;
}

And I have another library PilaElemento.h:

using namespace std;

typedef Elemento *Pila;

Pila crearPila(){
    Pila aux = NULL;
    return aux;
}

void apilar(Pila &pila, Elemento e) {
        Pila q = new(struct elemento);
        e.prox = pila;
        q = &e;
        pila = q;
}

void desapilar(Pila &pila) {
        Pila aux;   
        aux = pila;
        pila = pila->prox;
        delete aux;
}
Elemento tope(Pila &pila){
    return (elemento)*pila;
}

bool esVacia(Pila &pila) {
    bool log = false;
    if (pila==NULL) log= true;
    return log;
} 

Everything works fine, except Unstack, it shows me the following error message:

  

stack (5291,0x7fff765f5000) malloc: error for object 0x7fff5f143220:   pointer being freed was not allocated       * set to breakpoint in malloc_error_break to debug       Abort trap: 6

Basically I wanted to leave it this way so as not to touch the Pile Library, but only the element library (and I do not want to use POO)

    
asked by josedes 16.05.2017 в 18:24
source

2 answers

1
typedef struct elemento{
       int clave;
       string nombre;
       string apellido;
       struct elemento *prox;
}Elemento;

As I have said before: C ++ is not C. Structures do not need to pull typedef to generate readable code. This you have put is equivalent to:

struct Elemento{
       int clave;
       string nombre;
       string apellido;
       Elemento *prox;
};

Regarding this alias:

typedef Elemento *Pila;

Not only would it not be necessary but it will complicate the reading of the code, since you have to remember that Pila is a pointer (at least the name could have reflected such a characteristic: PilaPtr or ElementoPtr . .. I personally in this type of exercises would not use the alias.

We continue to convert pseudo C into C ++:

// Vale, funciona, pero ¿en serio?
Pila q = new(struct elemento);

// Lo que podría esperar encontrarse la gente
// Se ve raro que crees un objeto de un tipo y lo almacenes en un tipo distinto
Pila q = new Elemento;

// Lo que espera encontrarse la gente
Elemento* elemento = new Elemento;

And we started to expose the problems:

void apilar(Pila &pila, Elemento e) {
        Pila q = new Elemento; // <<--- 1
        e.prox = pila;
        q = &e; // <<--- 2
        pila = q;
}

Let's see:

  • You create an object with new ... and two lines below make the pointer point to another memory location ... losing the reserved memory with new
  • e is an object that you have passed by value . The object e literally dies when the code leaves the function, so the reference &e goes to point to garbage.
  • The function should look like this:

    void apilar(Pila &pila, Elemento e) {
            Pila q = new Elemento(e);
            q->prox = pila;
            pila = q;
    }
    
        
    answered by 17.05.2017 в 15:53
    0

    Thank you for answering PaperBirdMaster

    Here I put the Main.

    #include "elemento.h"
    #include "Pila-elemento.h"
    
    using namespace std;
    
    int main() {
    
        Pila pila = crearPila();
    
        Elemento e;
    
        e = crearElemento(10, "Ana", "Marquez");
        apilar(pila, e);
    
        e = crearElemento(30, "Luis", "Gonzalez");
        apilar(pila, e);
        apilar(pila, crearElemento(14, "Rosa", "Perez"));
        //imprimirElemento(tope(pila));
        cout << "-----------------------------------------------" << endl;
        cout << "--------------------DESAPILANDO----------------" << endl;
        while(!esVacia(pila)){
            imprimirElemento(tope(pila));
            desapilar(pila);                
            cout << "-----------------------------------------------" << endl;
        }
        return 0;
    }
    
        
    answered by 17.05.2017 в 14:58