[C] Memoria Condivisa

Messaggioda giacomovicinanza » 26/02/2022, 13:04

Salve a tutti. Sto riscontrando alcuni problemi nel momento in cui definisco TEsami *esami perchè ho provato a definirla prima della creazione della memoria ma non andava ed idem anche quando la definisco nel processo figlio. Non so come fare :/

/*****************************************************************
Il candidato completi il programma fornito, implementando
il main.
Il programma crea un processo figlio, che chiede all'utente
il numero di esami sostenuti, e per ciascun esame il numero di
CFU e il voto riportato.
Il processo figlio comunica le informazioni lette al processo padre,
che calcola e stampa la media degli esami (viene fornita la
funzione calcola_media per effettuare il calcolo).
La comunicazione tra processo figlio e processo padre deve avvenire
tramite un'area di memoria condivisa.
******************************************************************/

Codice:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/wait.h>

/*------------------------------------------
 * Struttura dati per rappresentare le
 * informazioni sugli esami
 *----------------------------------------*/
#define MAX_ESAMI 40

typedef struct {
    int numero_esami; /* Numero di esami sostenuti */
    int voto[MAX_ESAMI]; /* Voti riportati in ciascun esame sostenuto */
    int cfu[MAX_ESAMI]; /* Numero di CFU di ciascun esame sostenuto */
} TEsami;


/*--------------------------------------------
 * Calcola la media degli esami sostenuti.
 * Parametri di ingresso:
 *    esami    puntatore alla struttura contenente le informazioni
 *             sugli esami sostenuti
 * Valore di ritorno:
 *    la media dei voti degli esami, o 0 se non ci sono esami sostenuti.
 *------------------------------------------*/
double calcola_media(const TEsami *esami) {
    assert(esami!=NULL);
    int somma_pesata=0;
    int somma_cfu=0;
    int i;
    if (esami->numero_esami<=0)
        return 0.0;
    for(i=0; i<esami->numero_esami; i++) {
        somma_pesata += esami->voto[i]*esami->cfu[i];
        somma_cfu += esami->cfu[i];
    }
    return (double)somma_pesata / somma_cfu;
}


/*---------------------------
 * main
 *-------------------------*/
int main(int argc, char *argv[]) {
   /* Creazione dell'area di memoria */
  const int segment_size = MAX_ESAMI * sizeof (int);
  int segment_id = shmget (IPC_PRIVATE, segment_size, S_IRUSR | S_IWUSR);
 
  if(segment_id < 0) {
      printf("Errore in shmget\n");
      return -1;
  }
 
  pid_t pid = fork (); // la chiamata fork crea un processo figlio

  /* Il codice a seguire viene eseguito da entrambi i processi: padre e figlio */
  if(pid < 0) {
      /* Errore verificato */
      printf("Fork non riuscita\n");
      shmctl (segment_id, IPC_RMID, NULL);   // Deallocazione della memoria
      return -1;
  } else if(pid == 0){
      /* Processo Figlio */
      TEsami *esami = (TEsami *) shmat (segment_id, NULL, 0);   //  Per usare un'area di memoria condivsa, il processo deve collegarla al suo spazio di indirizzamento
      int i;

      printf ("Inserire il numero di esami sostenuti: ");
      scanf ("%d", &esami->numero_esami);
     
      if(esami->numero_esami > MAX_ESAMI) {
          return -1;
      }
     
      for(i = 0; i < esami->numero_esami; i++) {
          printf("Inserire il numero di CFU ed il voto riportato dell'esame %d conseguito: ", esami[i].numero_esami+1);
          scanf("%d %d", esami[i].voto, &esami[i].cfu);
      }
     
      shmdt(esami); // Quando un processo ha finito di usare un'area di memoria condivisa, deve scollegarla dal suo spazio di indirizzamento
      return 0;
  } else {
       /* Processo Padre */
        wait(NULL); // Attende la terminazione del figlio prima di accedere alla memoria
       
        TEsami *esami = (TEsami *) shmat (segment_id, NULL, 0);
        int i;
        int somma = 0;

        for(i = 0; i < esami->numero_esami; i++) {
          printf("Voto %d riportato dell'esame %d conseguito: ", esami[i].voto, esami[i].numero_esami+1);
          somma+ = esami[i+1].voto;
      }
     
      printf(" La media dell'alunno è: %f", calcola_media(somma));
        shmdt(esami); // Scollegare l'area di memoria
        shmctl(segment_id, IPC_RMID, NULL); // Deallocazione dell'area
        return 0;
  }
}
giacomovicinanza
Junior Member
Junior Member
 
Messaggio: 89 di 218
Iscritto il: 18/08/2021, 15:55

Re: [C] Memoria Condivisa

Messaggioda Quinzio » 27/02/2022, 11:45

Anche questa volta hai postato un codice che non compila, perche' ha un errore (facile da correggere) e poi diversi warnings che sono invece preoccupanti.
A dimostrazione che tra warning ed errori la differenza e' solo una bega del compilatore.
Questa e' l'ultima volta che guardo il codice se non compila ed ha dei warnings (da compilare con l'opzione -Wall).
Se un domani sul lavoro consegni del codice che non compila neanche hai gia' un piede fuori dalla porta.

Hai una discreta confusione in testa con i puntatori, i puntatori a strutture, gli array e gli operatori . punto -> freccia [] array

Comunque il codice corretto e' qui.
https://www.onlinegdb.com/fpcNeKJoF
Diciamo che almeno funziona, ma rimane qualcosa da mettere a posto.

In futuro usa questo tool, oltre a fare un copia incolla del codice.
Fai un confronto col tuo originale e poi vedi se e' chiaro.
Quinzio
Cannot live without
Cannot live without
 
Messaggio: 4803 di 10553
Iscritto il: 24/08/2010, 06:50

Re: [C] Memoria Condivisa

Messaggioda giacomovicinanza » 27/02/2022, 14:22

Grazie mille per il tuo prezioso aiuto. E' tutto chiaro
giacomovicinanza
Junior Member
Junior Member
 
Messaggio: 95 di 218
Iscritto il: 18/08/2021, 15:55


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite