Si crees que ese código "está bien" entonces estas muy confundido en el tema de punteros. Primero tienes que desechar todo lo que crees saber de punteros y empezar desde 0.
Algunos errores:
1. No inicializaste los punteros a 0. Simplemente imperdonable.
2. Como el nombre de tipo que escogiste para "Pila" es malísimo definiste un doble puntero donde sólo era necesario un simple puntero, tal vez por accidente.
3. En lugar de pasar la dirección del puntero a push y pop, le pasas el valor apuntado. Seguro que no compila por que la función espera un doble puntero.
Deberías pasar los parámetros por referencia, una gran ventaja de C++ para mejorar la legibilidad de tu código. También puede ayudar mucho adoptar un estilo de programación para darles nombres apropiados a los tipos.
#include <iostream>
typedef int Valor;
struct Nodo
{
Valor dato;
Nodo* abajo;
};
typedef Nodo* PNodo;
bool push(PNodo& pPila, const Valor val)
{
PNodo pNuevoNodo = new (std::nothrow) Nodo;
if (0 == pNuevoNodo) return false;
pNuevoNodo->abajo = pPila;
pNuevoNodo->dato = val;
pPila = pNuevoNodo;
return true;
}
bool pop(PNodo& pPila, Valor& val)
{
if (0 == pPila) return false;
PNodo pNodoDesechado = pPila;
pPila = pPila->abajo;
val = pNodoDesechado->dato;
delete pNodoDesechado;
return true;
}
void mostrarPila(PNodo pPila)
{
std::cout << "Pila:";
while (pPila)
{
std::cout << " " << pPila->dato;
pPila = pPila->abajo;
}
std::cout << std::endl;
}
int main()
{
PNodo pila = 0;
push(pila, 1);
mostrarPila(pila);
push(pila, 2);
mostrarPila(pila);
push(pila, 3);
mostrarPila(pila);
push(pila, 4);
mostrarPila(pila);
Valor v;
pop(pila, v);
mostrarPila(pila);
pop(pila, v);
mostrarPila(pila);
pop(pila, v);
mostrarPila(pila);
pop(pila, v);
mostrarPila(pila);
pop(pila, v);
mostrarPila(pila);
// Pausa
char c[1];
std::cin.getline(c, 1);
}
Esta es la versión usando clases, incluye constructor copia y operador de asignación. El operador new (std::nothrow) permite que la función push retorne falso si no existe suficiente memoria.
#include <iostream>
// Asi es en C++
typedef int Valor;
struct Nodo
{
Valor dato;
Nodo* abajo;
};
class Pila
{
public:
Pila() : pNodoSuperior(0) {}
~Pila()
{
limpiar();
}
Pila(const Pila& p) : pNodoSuperior(0)
{
*this = p;
}
const Pila& operator=(const Pila& p)
{
limpiar();
Nodo* pNodoActual = p.pNodoSuperior;
while (pNodoActual)
{
push(pNodoActual->dato);
pNodoActual = pNodoActual->abajo;
}
invertir();
return *this;
}
void limpiar()
{
Nodo* pNodoTemp;
while (pNodoSuperior)
{
pNodoTemp = pNodoSuperior;
pNodoSuperior = pNodoSuperior->abajo;
delete pNodoTemp;
}
}
bool push(const Valor& val)
{
Nodo* pNuevoNodo = new (std::nothrow) Nodo;
if (0 == pNuevoNodo) return false;
pNuevoNodo->abajo = pNodoSuperior;
pNuevoNodo->dato = val;
pNodoSuperior = pNuevoNodo;
return true;
}
bool pop(Valor& val)
{
if (0 == pNodoSuperior) return false;
Nodo* pNodoDesechado = pNodoSuperior;
pNodoSuperior = pNodoSuperior->abajo;
val = pNodoDesechado->dato;
delete pNodoDesechado;
return true;
}
void invertir()
{
Nodo* pNodoActual = pNodoSuperior;
Nodo* pNodoArriba = 0;
Nodo* pNodoAbajo;
while (pNodoActual)
{
pNodoAbajo = pNodoActual->abajo;
pNodoActual->abajo = pNodoArriba;
pNodoArriba = pNodoActual;
pNodoActual = pNodoAbajo;
}
pNodoSuperior = pNodoArriba;
}
void mostrar() const
{
std::cout << "Pila: ";
Nodo* pNodoTemp = pNodoSuperior;
while (pNodoTemp)
{
std::cout << " " << pNodoTemp->dato;
pNodoTemp = pNodoTemp->abajo;
}
std::cout << std::endl;
}
private:
Nodo* pNodoSuperior;
};
int main()
{
Pila p;
p.push(1);
p.mostrar();
p.push(2);
p.mostrar();
p.push(3);
p.mostrar();
p.push(4);
p.mostrar();
Valor v;
Pila p1(p);
p.pop(v);
p.mostrar();
p.pop(v);
p.mostrar();
p.pop(v);
p.mostrar();
p.pop(v);
p.mostrar();
p1.mostrar();
p1.invertir();
p1.mostrar();
// Pausa
char c[1];
std::cin.getline(c, 1);
}