Funzioni a parametri variabili *Void - SegmentationFault

di il
6 risposte

Funzioni a parametri variabili *Void - SegmentationFault

Premetto che è la prima volta che scrivo della funzioni a parametri variabili..
Quello che devo fare è scrivere una funzione a parametri variabili che indipendentemente dal tipo di dato in ingresso, sia in grado di restituirne il valore massimo tra i dati.
Da traccia la funzione deve contenere il numero dei dati di ingresso, come parametro fisso.
L'ho pensata utilizzando librerie per i vari tipi di dati, con i rispettivi confronti.
(Posso dare come parametro fisso di questo tipo di funzione un puntatore a funzione ?! )

Considerando l'esempio di tipi di dati INT..
main.c
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "datoINT.h"

typedef int (*COMPARE)(void * , void * );

void * myMax (COMPARE compare, int quanti,...);

void * myMax(COMPARE compare, int quanti,...)
{
    void *x=NULL; void *max=NULL;
    va_list argp;
    va_start(argp, quanti);

    max=va_arg(argp,void *);
    quanti--;

    while (quanti-- >0)
    {
        x=va_arg(argp,void *);
        if(compare(max,x)>0) max=x;

    }

    va_end(argp);
    return max;

}

int main()
{
    void * max;

    max=myMax(compareINT,4,2,10,6,4);
    printf("Il massimo tra 2,3,6,4: %d\n",*(int*)max);

    return 0;
}
datoINT.h
#ifndef DATOINT_H_INCLUDED
#define DATOINT_H_INCLUDED

int compareINT(void * a, void * b);

#endif // DATOINT_H_INCLUDED
datoINT.c
#include <stdio.h>
#include <stdlib.h>
#include "datoINT.h"

int compareINT (void * a, void * b)
{
    int a1= *(int*)a; //errore segmentation Fault
    int b1= *(int*)b;
    return a1-b1;
}
L'esecuzione si interrompe per un errore di segmentation fault al rigo che ho commentato.
Ed inoltre non credo di passare in maniera corretta l'input alla funzione.. mmm..

6 Risposte

  • Re: Funzioni a parametri variabili *Void - SegmentationFault

    Stai passando interi a myMax non dei puntatori, pertanto quando li recuperi tramite va_arg et similia tali interi sono brutalmente convertiti a puntatori void* non dereferenziabili.
    Per riottenere l'intero basta un cast a int come indicato.
    
    int compareINT (void * a, void * b)
    {
        int a1= (int)a; //errore segmentation Fault
        int b1= (int)b;
        return b1-a1;
    }
    
  • Re: Funzioni a parametri variabili *Void - SegmentationFault

    Ok grazie mille hai ragione! Così infatti non ho problemi.
    E se invece di int volessi passare proprio dei puntatori a void direttamente dalla chiamata di myMax? Ovviamente avendo in realtà degli int, ed effettuando un cast a (void*) nella chiamata della funzione. Ottengo comunque lo stesso errore di cui sopra. Non posso farlo?
  • Re: Funzioni a parametri variabili *Void - SegmentationFault

    In questo modo? (lo illustro con solo una variabile).
    
         int var = 10;
         max=myMax(compareINT,4,(void*)&var);
    
    o in questo?
    
         max=myMax(compareINT,4,(void*)10);
    
    Il secondo caso ricade in quanto già detto.
    Il primo caso a volte si verifica, ma nel tuo specifico può essere solo una complicazione in più.
    A ogni modo con il primo caso va bene la compareINT originale tua.

    Il punto è che un puntatore void* può puntare a qualsiasi cosa tranne a puntatori a funzione (lo standard lo vieta anche se alcuni compilatori fanno finta di niente), ma si perde ogni tipo di informazione associata.
    Ossia cosa stia puntando un puntatore a void* lo deve sempre sapere il programmatore.
  • Re: Funzioni a parametri variabili *Void - SegmentationFault

    Ho capito! Grazie.
    Quindi tu mi consigli come soluzione migliore di modificare solo la mia compareINT come mi hai indicato? Considerando che io quello che devo fare è scrivere una funzione myMax che possa essere eseguita per ogni tipo di dato.
    Essendo la prima volta che scrivo queste funzioni a parametri variabili, sto cercando proprio di capire (errori miei a parte) le soluzioni migliori e consigliate per scriverle.
  • Re: Funzioni a parametri variabili *Void - SegmentationFault

    Quindi tu mi consigli come soluzione migliore di modificare solo la mia compareINT come mi hai indicato?
    Si. In base al tipo dei parametri andrà ovviamente modificata.
    qsort è un tipico esempio di funzione di libreria che prende un puntatore a funzione per la comparazione dei dati.
  • Re: Funzioni a parametri variabili *Void - SegmentationFault

    Ok grazie.
Devi accedere o registrarti per scrivere nel forum
6 risposte