Hello there people, I hope you can help me with this one.
I'm having a very serious problem when using the Top() method of a stack, difined like this:

template<class T>
T Stack<T>::Top() const
{// Return top element.
   if (IsEmpty()) throw OutOfBounds(); // Top fails
   else return stack[top];
}

and also:

template<class T>
T LinkedStack<T>::Top() const
{// Return top element.
   if (IsEmpty()) throw OutOfBounds();
   return top->data;
}

The thing is this:
If I say, for example:

x = stack.Top()
cout << x;

x shows just fine, but the data stored in the top of the stack becomes corrupted.
That means if I call Top() again it will show horribly distorted data.
It only happens when I use a class I defined, but I'm pretty sure it's OK.

Any Ideas?? Please tell everything that comes to mind

Here's the class but it's in Spanish(As I said it should be all fine):

class Mascota{
    char * especie;
    char * nombre;
    int * edad;
    public:
    Mascota();
    Mascota(const char*,const char*,int);
    ~Mascota();
    void Set(istream&);
    bool operator==(const Mascota&)const;
    bool operator!=(const Mascota&)const;
    Mascota & operator=(const Mascota&);
    void imprimir(ostream&)const;
};

Mascota::Mascota(){
    especie = new char[1];
    nombre = new char[1];
    edad = new int;
    especie[0]= '\0';
    nombre[0]= '\0';
    *edad = 0;
}

Mascota::Mascota(const char * laEspecie, const char * elNombre, int laEdad){
    especie = new char[strlen(laEspecie)+1];
    strcpy(especie,laEspecie);
    nombre = new char[strlen(elNombre)+1];
    strcpy(nombre,elNombre);
    edad = new int;
    *edad = laEdad;
}

Mascota::~Mascota(){
    delete[] nombre;
    delete[] especie;
    delete edad;
}

bool Mascota::operator==(const Mascota & x)const{
    bool resultado = false;
    if(*edad==*x.edad && strcmp(especie, x.especie)==0 && strcmp(nombre, x.nombre)==0)
    resultado = true;
    return resultado;
}

bool Mascota::operator!=(const Mascota&x)const{
    bool resultado = false;
    if(*edad!=*x.edad || 0!=strcmp(especie,x.especie) || 0!=strcmp(nombre,x.nombre))
    resultado = true;
    return resultado;
}

Mascota & Mascota::operator=(const Mascota& x){
    delete edad; delete[] nombre; delete[] especie;
    especie = new char[strlen(x.especie)+1];
    nombre = new char[strlen(x.nombre)+1];
    edad = new int;
    strcpy(especie, x.especie);
    strcpy(nombre, x.nombre);
    *edad = *x.edad;
    return *this;
}

void Mascota::Set(istream&in){
    edad = new int;
    especie = new char[35];
    nombre = new char[35];
    cout << "Ingrese el nombre de su mascota: ";
    gets(nombre);
    cout << "Ingrese la especie de su mascota: ";
    gets(especie);
    cout << "Ingrese la edad en anios de su mascota: ";
    in >> *edad;
    cout << endl;
}

void Mascota::imprimir(ostream & out)const{
    if(edad == NULL || *edad<0){
        out << "Mascota sin informacion";
    }else{
        out << "Nombre: " << endl;
        puts(nombre);
    }
    out << endl << endl;
}

ostream & operator<<(ostream & out, const Mascota & x){
    x.imprimir(out);
    return out;
}

istream & operator>>(istream&in,Mascota&x){
    x.Set(in);
    return in;
}

You need to show more code.

Which code exactly?

But just tell me if you can think of something...

Edited 5 Years Ago by flowerzink: n/a

Where is the copy-constructor in your Mascota class? That's the piece missing, and what an important one!

I highly, highly recommend that you use std::string instead of char* and that you store the integer edad by value, not by pointer. Pointers are evil and you are suffering it right now.

If you choose to keep pointers, there are a few errors in your code. First, your assignment operator does not check for self-assignment (which will cause a seg-fault as it is now). You should add a if(this != &x) to check for self-assignment. Better yet, use the copy-and-swap idiom.

Finally, your Set() function does not delete the old pointers before you reallocate memory.

Comments
Helped me solve my problem

Where is the copy-constructor in your Mascota class? That's the piece missing, and what an important one!

I highly, highly recommend that you use std::string instead of char* and that you store the integer edad by value, not by pointer. Pointers are evil and you are suffering it right now.

If you choose to keep pointers, there are a few errors in your code. First, your assignment operator does not check for self-assignment (which will cause a seg-fault as it is now). You should add a if(this != &x) to check for self-assignment. Better yet, use the copy-and-swap idiom.

Finally, your Set() function does not delete the old pointers before you reallocate memory.

Wow, thanks a lot!! I think the problem was the copy-constructor. I have to keep the pointers you see, my teacher want to prove our dinamic memory allocation abilities :P

That solves it, thanks!

This question has already been answered. Start a new discussion instead.