Il programma (seconda versione) mi provoca l'errore di segmentazione,
perche' non viene allocata memoria per la struct Tstack.
Ho modificato crea_stack(), in modo che allochi memoria e renda
in uscita il puntatore alla memoria allocata; se l'allocazione non riesce,
la funzione restituisce il valore NULL.
Ho modificato Pop(), per evitare che si tenti di estrarre un elemento
se la pila e' vuota; la versione originale decrementa l'indice dell'array
anche se la pila e' vuota, quindi va a leggere valori posti fuori dall'array
(indici negativi) con effetti catastrofici.
Ho creato la funzione mostra_stack(), per visualizzare l'effetto
delle varie operazioni.
Ho eliminato l'istruzione system(), sconsigliata da Robert C.Seacord
(The CERT C Coding Standard, 2014, Pearson Education, 978-0-321-98404-3,
pp.319-325).
Ho indicato espressamente con "void" le funzioni che non ricevono
argomenti, seguendo il consiglio di LPs in questa discussione:
https://www.iprogrammatori.it/forum-programmazione/cplusplus/creazione-stampa-lista-t31335.html
Forse sarebbe meglio creare due funzioni svuota_stack(),
per svuotare lo stack lasciando allocata la memoria,
e distruggi_stack() per deallocare la memoria.
Si potrebbe anche cambiare l'impostazione generale:
invece di inserire in un colpo solo tutti i numeri,
per poi procedere solo con le estrazioni, si potrebbero
prevedere le due opzioni "inserisci numero" ed "estrai numero";
cosi' l'utente potrebbe alternare a proprio piacimento
le operazioni di inserimento ed estrazione.
/* EPAD.C */
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
# define MAXVETT 100
typedef struct
{
int dim; //top
int array[MAXVETT];
} Tstack;
//PROTOTIPI DI FUNZIONE
//Tstack crea_stack();
Tstack *crea_stack(void);
void distruggi_stack(Tstack *stack);
//inserimento elemento
void Push(Tstack *stack, int x); //x elemento da inserire
//prelievo, ci ritorna l'elemento in cima
int Pop(Tstack *stack, bool *ok);
bool is_empty(Tstack *stack);
bool is_full(Tstack *stack);
int menu(void);
void mostra_stack(Tstack *p);
/* --------------------------------------------------------------- */
int main(void)
{
Tstack *pila1;
int scelta;
int dim,elemento,i;
// esito estrazione
bool ok_estraz;
// *pila1 = crea_stack ();
pila1 = crea_stack();
// se l'allocazione non e' riuscita,
// esce dal programma
if (pila1 == NULL)
{
printf("\n%s\n\n", "Memoria heap insufficiente");
return 0;
}
while(scelta = menu())
{
switch(scelta)
{
case 1:
// system("CLS");
if(is_empty(pila1) == true)
{
printf("Quanti elementi si vuole inserire?: ");
scanf("%d", &dim);
for(i = 0; i < dim; i++)
{
printf("inserire il %do valore: ", i + 1);
scanf("%d", &elemento);
Push(pila1, elemento);
}
}
mostra_stack(pila1);
// system("PAUSE");
break;
case 2:
mostra_stack(pila1);
elemento = Pop(pila1, &ok_estraz);
if (ok_estraz)
{
printf("\n%s%d\n", "Numero estratto dallo stack: ", elemento);
mostra_stack(pila1);
}
else
{
printf("\n%s\n\n", "Nessuna estrazione, lo stack e' vuoto");
}
// system("CLS");
// system("PAUSE");
break;
case 3:
// system("CLS");
return 0;
// system("PAUSE");
break;
} // fine switch
} // fine while
// dealloca la memoria
if (pila1 != NULL)
{
free(pila1);
pila1 = NULL;
}
return 0;
}
/* ----------------------------------------------------------------------------- */
//DEFINIZIONE DI FUNZIONI
//Tstack crea_stack()
//{
// Tstack pila;
// pila.dim = 0;
// return pila;
//}
// alloca memoria per una struct Tstack;
// rende in uscita il valore del relativo puntatore
// se l'allocaz. riesce, altrimenti rende NULL
Tstack *crea_stack(void)
{
Tstack *pila;
// alloca memoria
pila = malloc(sizeof(Tstack));
if (pila != NULL)
{
pila->dim = 0;
}
return pila;
}
// svuota lo stack, pero' la memoria resta allocata
void distruggi_stack(Tstack *stack)
{
stack->dim = 0;
}
void Push(Tstack *stack, int x)
{
//l'elemento deve essere inserito in cima alla nostra struttura dati in
// posizione dim
stack->array[stack->dim] = x;
stack->dim++;
}
int Pop(Tstack *stack, bool *ok)
{
int k; //elemento in ultima posizione dell'array dello stack
// se la pila e' vuota, non puo' estrarre nessun numero
if (stack->dim < 1)
{
*ok = false;
return 0;
}
// se arriva fin qui, significa che la pila non e' vuota
// e che puo' estrarre un numero
k = stack->array[stack->dim - 1];
(stack->dim)--;
*ok = true;
return k;
}
bool is_empty(Tstack *stack)
{
return stack->dim == 0;
//nel main:
//if(is_empty==true) significa che è vuota
//se è falsa allora nello stack c'è qualcosa
}
bool is_full(Tstack *stack)
{
return stack->dim == MAXVETT;
}
int menu(void)
{
int scelta;
printf("[1] inserisci nello stack\n");
printf("[2] elimina dallo stack\n");
printf("[3] esci\n");
scanf("%d", &scelta);
return scelta;
}
void mostra_stack(Tstack *p)
{
int i;
if (p->dim == 0)
{
printf("\n%s\n\n", "Stack vuoto");
}
else
{
printf("\n%s", "Stack: ");
for (i = 0; i < p->dim; i++)
{
printf("%d%s", p->array[i], " ");
}
printf("\n\n");
}
}
/* --------------------- FINE EPAD.C ---------------------------- */