(c) segmentation fault (core dump creato)

di il
32 risposte

(c) segmentation fault (core dump creato)

Buonasera,
premetto che sono alle prime armi, ma vorrei chiedere se gentilmente qualcuno mi può aiutare a risolvere questo errore:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

typedef struct Mago {
char nome_mago[256];
char* c_mago;
unsigned int punti_vita;
struct Carta* inizio_mazzo;
struct Carta* fine_mazzo;
struct Carta* mano[6];
struct Carta* campo[4];
}mago;

static struct Mago Mago;

mago* scelta_classe (mago *pMago)
{

int scelta;

printf("Scegliere la classe del mago che si desidera essere: \n 1. tenebre \n 2. vita \n 3. luce \n\n");

scanf("%d", &scelta);
((getchar()) != '\n');
pMago -> c_mago = NULL;



switch (scelta) {
case 1:
pMago -> c_mago = "tenebre";
break;

case 2:
pMago -> c_mago = "vita";
//printf("Il coso: %s\n", pMago -> c_mago );
break;

case 3:
pMago -> c_mago = "luce";
break;
}
return pMago;
}


void stampa (mago *pMago) {
printf("la classe del mago è: %s\n", pMago -> c_mago);
}


int main () {
mago* pMago = scelta_classe (pMago);
stampa(pMago);
}

32 Risposte

  • Re: (c) segmentation fault (core dump creato)

    Il tag code va aperto a inizio codice e chiuso alla fine.

    Comunque alla funzione hai passato un puntatore di tipo *Mago, ma a cosa punta? O lo fai puntare a una variabile di tipo Mago, oppure l'oggetto Mago lo allochi dinamicamente chiamando la funzione malloc.
  • Re: (c) segmentation fault (core dump creato)

    Il puntatore di tipo *Mago punta al campo "c_mago", o sbaglio ?
  • Re: (c) segmentation fault (core dump creato)

    Ho modificato questo pezzo aggiungendo la malloc e il problema sembra essere risolto. L'unica cosa è che ho paura che al compilatore vada bene, ma non sia giusto il modo in cui l'ho fatto:

    struct Mago* scelta_classe (struct Mago* pMago)
    {

    pMago = (struct Mago*) (malloc (sizeof(char*)));
    pMago -> c_mago = NULL;
    int scelta;

    printf("Scegliere la classe del mago che si desidera essere: \n 1. tenembre \n 2. vita \n 3. luce \n");
    scanf("%d", &scelta);

    switch (scelta) {
    case 1:
    pMago -> c_mago = "tenebre";
    break;

    case 2:
    pMago -> c_mago = "vita";
    break;

    case 3:
    pMago -> c_mago = "luce";
    break;

    default:
    printf("Errore: Scegli una classe valida \n");
    }
    free(pMago);
    return pMago;
    }
  • Re: (c) segmentation fault (core dump creato)

    Il puntatore può puntare a una variabile di tipo struct Mago, poi con l'operatore "freccetta" accede ai vari campi. Ma devi essere tu a farlo puntare a qualcosa assegnandogli il rispettivo indirizzo.
  • Re: (c) segmentation fault (core dump creato)

    Puoi postare tutto il codice?
  • Re: (c) segmentation fault (core dump creato)

    Alexv ha scritto:


    Puoi postare tutto il codice?
    Essendo questo che sto postando, una parte di un programma più esteso, ci sono nomi che fanno riferimento ad altre strutture. Questo pezzo l'ho scritto in un file prova.


    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>

    typedef struct Mago {
    char nome_mago[256];
    char* c_mago;
    char* seme_carta;
    unsigned int punti_vita;
    struct Carta* inizio_mazzo;
    struct Carta* fine_mazzo;
    struct Carta* mano[6];
    struct Carta* campo[4];
    }mago;

    struct Mago* scelta_classe (struct Mago* pMago)
    {

    pMago = (struct Mago*) (malloc (sizeof(char*)));
    pMago -> c_mago = NULL;
    int scelta;

    printf("Scegliere la classe del mago che si desidera essere: \n 1. tenembre \n 2. vita \n 3. luce \n\n");
    scanf("%d", &scelta);

    switch (scelta) {
    case 1:
    pMago -> c_mago = "tenebre";
    break;

    case 2:
    pMago -> c_mago = "vita";
    break;

    case 3:
    pMago -> c_mago = "luce";
    break;

    default:
    printf("Errore: Scegli una classe valida \n");
    }
    free(pMago);
    return pMago;
    }

    static void stampa_classe (struct Mago* pMago) {
    printf("\nLa classe del mago è: %s \n", pMago -> c_mago );
    }

    int main () {
    mago* pMago = scelta_classe (pMago);
    stampa_classe (pMago);
    }
  • Re: (c) segmentation fault (core dump creato)

    Alexv ha scritto:


    Il puntatore può puntare a una variabile di tipo struct Mago, poi con l'operatore "freccetta" accede ai vari campi. Ma devi essere tu a farlo puntare a qualcosa assegnandogli il rispettivo indirizzo.
    Scusa l'inettitudine, quindi cosa dovrei aggiungere? il campo char* c_mago non è una variabile di tipo struct Mago? E il puntatore non punta all'indirizzo di quest'ultimo campo?
  • Re: (c) segmentation fault (core dump creato)

    L'argomento della funzione non deve essere usato, la prima malloc è sbagliata, manca la malloc per la stringa, la free non deve essere fatta ... rivedi il codice
    
    
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <string.h>		// da aggiungere
    
    
    typedef struct Mago {
    	char nome_mago[256];
    	char* c_mago;
    	char* seme_carta;
    	unsigned int punti_vita;
    	struct Carta* inizio_mazzo;
    	struct Carta* fine_mazzo;
    	struct Carta* mano[6];
    	struct Carta* campo[4];
    }mago;
    
    struct Mago* scelta_classe()
    {
    	struct Mago* pMago = (struct Mago*)(malloc(sizeof(struct Mago)));
    	pMago->c_mago = NULL;
    	pMago->c_mago = (char*)malloc(8);
    	int scelta;
    
    	printf("Scegliere la classe del mago che si desidera essere: \n 1. tenembre \n 2. vita \n 3. luce \n\n");
    	scanf("%d", &scelta);
    
    	switch (scelta) {
    	case 1:
    		strcpy(pMago->c_mago, "tenebre");
    		break;
    
    	case 2:
    		strcpy(pMago->c_mago, "vita");
    		break;
    
    	case 3:
    		strcpy(pMago->c_mago, "luce");
    		break;
    
    	default:
    		strcpy(pMago->c_mago, "?");
    		printf("Errore: Scegli una classe valida \n");
    	}
    
    	return pMago;
    }
    
    static void stampa_classe(struct Mago* pMago) {
    	printf("\nLa classe del mago e': %s \n", pMago->c_mago);
    }
    
    int main() {
    	mago* pMago = scelta_classe();
    	stampa_classe(pMago);
    }
    
    
  • Re: (c) segmentation fault (core dump creato)

    Elia06_11 ha scritto:


    Scusa l'inettitudine, quindi cosa dovrei aggiungere? il campo char* c_mago non è una variabile di tipo struct Mago? E il puntatore non punta all'indirizzo di quest'ultimo campo?
    No, è un puntatore a stringa.
    La variabile di tipo Mago è quella che viene allocata con la malloc, che infatti andrebbe scritta così:
    
    (mago*) (malloc (sizeof(mago)));
    
    (hai usato il typedef per non dover ripetere la parola "struct")

    Per il resto il secondo codice che hai postato non dovrebbe dare problemi a runtime, tuttavia quando va in errore ed esegui la free, ti conviene anche annullare il puntatore (non lo fa in automatico) e quindi restituirne uno nullo, altrimenti fuori dalla funzione il programma non ha modo di controllare se sta puntando a qualcosa di valido.

    PS: @oregon perché dici che la free non va fatta? Dal momento che ha allocato nella funzione, ci sta che se qualcosa va storto (parametro errato) sia la funzione stessa a ripulire la memoria.
  • Re: (c) segmentation fault (core dump creato)

    Ho anche provato a modificarlo così e non mi da errori.
    
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    
    typedef struct Mago {
      char nome_mago[256];
      char* c_mago;
      char* seme_carta;
      unsigned int punti_vita;
      struct Carta* inizio_mazzo;
      struct Carta* fine_mazzo;
      struct Carta* mano[6];
      struct Carta* campo[4];
    }mago;
    
    mago Mago;
    
    mago* scelta_classe (mago* pMago)
    {
    
        pMago = &Mago;
        pMago -> c_mago = NULL;
        int scelta;
    
        printf("Scegliere la classe del mago che si desidera essere: \n 1. tenembre \n 2. vita \n 3. luce \n\n");
        scanf("%d", &scelta);
    
        switch (scelta) {
          case 1:
          pMago -> c_mago = "tenebre";
          break;
    
          case 2:
          pMago -> c_mago = "vita";
          break;
    
          case 3:
          pMago -> c_mago = "luce";
          break;
    
          default:
          printf("Errore: Scegli una classe valida \n");
        }
        return pMago;
    }
    
    static void stampa_classe (mago* pMago) {
      printf("\nLa classe del mago è: %s \n", pMago -> c_mago );
    }
    
    int main () {
    mago* pMago = scelta_classe (pMago);
    stampa_classe (pMago);
    }
    
    
  • Re: (c) segmentation fault (core dump creato)

    @Elia... hai letto la mia risposta?

    @Alexv ... se usi la free il puntatore restituito dalla funzione e usato in seguito nel main non sarà più valido, come per la stringa all'interno della struttura. La responsabilità della liberazione della memoria è del chiamante (ovvero del main)
  • Re: (c) segmentation fault (core dump creato)

    Vedi il codice postato da oregon.
  • Re: (c) segmentation fault (core dump creato)

    Alexv ha scritto:


    Elia06_11 ha scritto:


    Scusa l'inettitudine, quindi cosa dovrei aggiungere? il campo char* c_mago non è una variabile di tipo struct Mago? E il puntatore non punta all'indirizzo di quest'ultimo campo?
    No, è un puntatore a stringa.
    La variabile di tipo Mago è quella che viene allocata con la malloc, che infatti andrebbe scritta così:
    
    (mago*) (malloc (sizeof(mago)));
    
    (hai usato il typedef per non dover ripetere la parola "struct")

    Per il resto il secondo codice che hai postato non dovrebbe dare problemi a runtime, tuttavia quando va in errore ed esegui la free, ti conviene anche annullare il puntatore (non lo fa in automatico) e quindi restituirne uno nullo, altrimenti fuori dalla funzione il programma non ha modo di controllare se sta puntando a qualcosa di valido.

    PS: @oregon perché dici che la free non va fatta? Dal momento che ha allocato nella funzione, ci sta che se qualcosa va storto (parametro errato) sia la funzione stessa a ripulire la memoria.
    Vi spiego molto brevemente, il programma si basa su un gioco di carte. Due giocatori impersonificano due maghi, ed essi devono scegliere la classe del proprio mago, che è un campo della struttura. Quindi lo scopo di questo pezzo, è quello di modificare il campo c_mago (ossia la classe del mago) e copiarci la scelta del giocatore.
  • Re: (c) segmentation fault (core dump creato)

    @Elia ... invece di continuare a scrivere e andare a caso, vuoi dare un'occhiata alla mia risposta?
Devi accedere o registrarti per scrivere nel forum
32 risposte