Puntatore ed errore di segmentazione

di Anonimizzato17918 il
2 risposte
Salve ragazzi,
sto facendo gli esercizi del capitolo 7 del libro di Aguilar (che usiamo all'universita).
L'esercizio mi chiede di creare un db con un array di struttura. Sto lavorando su Ubuntu e compilo da terminale con gcc (metodo usato all'uni)..

Qui il codice (volevo metterne solo una parte, ma se posso volevo chiedere altre cose):
#include <stdio.h>
#include <stdlib.h>

enum {MOROSO, RITARDO, PAGATO};

struct anagrafica{
                char nome[20];
                int ordini;
                float prezzo_unit;
                int stato;
};

const int MAX=10;  //dovrebbe essere 100 

void inserisci(struct anagrafica a[], int* i){
     int val,temp;
     float ftemp;
     printf("Cliente n°%d\n", *i+1);
     printf("Inserire nome cliente: \n");
     scanf("%20s", a[*i].nome);
     printf("Inserire pezzi ordinati:\n");
     scanf("%d", &temp);      //ho dovuto fare sto giro per evitare unn warning 
     a[*i].ordini=temp;           // (o forse un errore nel compilatore)
     printf("Inserire prezzo unitario:\n");
     scanf("%f", &ftemp);
     a[*i].prezzo_unit=ftemp;
     printf("Inserire stato:\n1-Moroso\n2-InRitardo\n3-Pagato");
     scanf("%d", &val);
     switch (val){
         case 1: a[*i].stato = MOROSO;
         case 2: a[*i].stato = RITARDO;
         case 3: a[*i].stato = PAGATO;
     }
     
}

void stampa(struct anagrafica a[], int* i){
     int val,n;
     for (n=0; n<*i; n++){
             printf("%d - %20s\t%d\t%f\t", *i,a[*i].nome,a[*i].ordini,a[*i].prezzo_unit);
             val=a[*i].stato;
             switch(val){
                case 0: printf("MOROSO"); break;
                case 1: printf("IN RITARDO"); break;
                case 2: printf("PAGATO"); break;
             }
      }
}

int menu(){
        int i,n;
        for (n=0;n<30;n++) printf("\n");
        printf("++++++++++++++++++++++++++\n");
        printf("+  Anagrafica clienti    +\n");
        printf("+  Programma strutture   +\n");
        printf("+   1 - inserisci i dati +\n");
        printf("+   2 - leggi i dati     +\n");
        printf("+   0 - uscita           +\n");
        printf("+                        +\n");
        printf("++++++++++++++++++++++++++\n");
        scanf ("%d", &i);
        printf("prima di return");
        return i;
}

int vuoto(struct anagrafica a[]){  //serve per trovare il primo array vuoto
        int i;
        for(i=0;i<MAX;i++){
                printf("%d\t", i);
                if (a[i].nome[0]=='\0') return i;
        } return 99;
        
}

void main(){
     int scelta;
     int* i;
     struct anagrafica cliente[MAX];

     do {
        scelta=menu();
        *i=vuoto(cliente);     //penso che sia qui l'errore
       if (scelta==1) inserisci (cliente, i);
        if (scelta==2) stampa (cliente, i);
        
     }while (scelta!=0);
     
     
}


Sono quasi sicuro che l'errore sia nel main(), quando assegno *i.

Secondo voi oltre all'errore di segmentazione ho fatto altri errori concettuali?

Grazie

2 Risposte

  • Ma perché un puntatore?

    Se restituisci un int allora è un int che devi usare

    int i;

    i = vuoto(....
  • Oregon ha ragione nel chiederti perché un puntatore quando basta un int.

    Od ogni modo l'errore concettuale sta nel comprendere che non puoi assegnare un valore intero ad *i se prima non allochi lo spazio di memoria per contenerlo.
    Quando dichiari un puntatore viene riservato spazio per memorizzare un indirizzo di memoria e non spazio per contenere dati.
    Lo spazio che riserverebbe il sistema ad un puntatore ad int è lo stesso che riserverebbe al puntatore ad una struct di centinaia di campi.

    Quindi fermo restando che anche a mio avviso in questo caso basta: int i;
    Ovviamente poi devi utilizzare & per riferirti ad i nelle funzioni che chiami.
    
    /* Se scrivi: */
    int *i = (int *)malloc(sizeof(int));
    /* Eventuali controlli */
    
    Tutto torna a posto.
Devi accedere o registrarti per scrivere nel forum
2 risposte