[C++] Funzioni che restituiscono array

Messaggioda mklplo » 25/02/2019, 16:27

Salve, a scuola ( al liceo) stiamo facendo c++ e stavo cercando di fare una funzione inserita la dimensione del vettore mi restituisse il vettore; tuttavia, ogni volta che lo faccio mi esce l'errore "segmentation fault". Se non vi reca disturbo, potreste spiegarmi dove sbaglio?
Il codice è questo:
Codice:
#include <iostream>
using namespace std;

float* costruzione(int i,int v){
    float a[i];
    for(int x=0;x<i;x++){
        cout<<"Inserire la componente numero "<<x+1<<" del vettore numero "<<v<<endl;
        cin>>a[x];
    }
    return a;
}
int main (){
    int i;
    cout<<"Inserire la dimensione del vettore"<<endl;
    cin>>i;
    float *a;
    float *b;
    a=costruzione(i,1);
    b=costruzione(i,2);
    for(int j=0;j<i;j++){
        cout<<a[i]+b[i]<<endl;
    }
    system("Pause");
    return 0;
}
mklplo
Advanced Member
Advanced Member
 
Messaggio: 812 di 2272
Iscritto il: 21/02/2016, 16:05

Re: [C++] Funzioni che restituiscono array

Messaggioda apatriarca » 02/03/2019, 21:04

La vita del tuo array è limitato alla funzione costruzione ed è quindi invalido cercare di accedere alla sua memoria una volta usciti da questa. Non puoi insomma restituire un puntatore ad una variabile locale ad una funzione. Il fatto che questa variabile sia un array non cambia nulla. La dichiarazione del tuo array è inoltre invalida in C++, ma supportata come estensione da alcuni compilatori. Lo standard C++ richiede che la dimensione di un array sia un'espressione costante. Un argomento alla funzione non è certamente costante. Il tuo programma potrebbe quindi compilare o meno a seconda del compilatore scelto e dagli argomenti passati a questi compilatori.

Siccome vuoi restituire tale array non ha comunque senso allocare staticamente il tuo array nella funzione. Il metodo corretto è quello di usare l'allocazione dinamica o passare l'array (quindi già creato con la dimensione corretta nel main) alla funzione.

Devi insomma fare qualcosa come il seguente:
Codice:
#include <iostream>

float* costruzione(int i, int v)
{
    float *a = new float[i];
    for (int x = 0; x < i; x++) {
        std::cout << "Inserire la componente numero " << x + 1 << " del vettore numero " << v << std::endl;
        std::cin >> a[x];
    }
    return a;
}

int main ()
{
    std::cout << "Inserire la dimensione del vettore" << std::endl;
   
    int i;
    std::cin >> i;
   
    float *a = costruzione(i, 1);
    float *b = costruzione(i, 2);

    for (int j = 0; j < i; j++) {
        std::cout << a[i] + b[i] << std::endl;
    }

    // Devi deallocare la memoria qui..
    delete[] a;
    delete[] b;
}


Ovviamente c'è anche la possibilità di usare qualcosa come un std::vector<float> in C++ "moderno" ma il tuo professore è certamente rimasto un po' indietro.
apatriarca
Moderatore
Moderatore
 
Messaggio: 5200 di 10435
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C++] Funzioni che restituiscono array

Messaggioda mklplo » 03/03/2019, 10:55

Grazie per la risposta.
Volevo chiderti, dato che la prof non ha ancora spiegato i puntatori in modo dettagliato (solo un piccolissimo accenno), cosa intendi per "un puntatore ad una variabile locale ad una funzione" e "deallocare"? E cosa vuol dire le stringe "float *a=new float [i]" ?
mklplo
Advanced Member
Advanced Member
 
Messaggio: 813 di 2272
Iscritto il: 21/02/2016, 16:05

Re: [C++] Funzioni che restituiscono array

Messaggioda apatriarca » 03/03/2019, 14:35

Un puntatore è quello che hai usato per restituire il tuo array. E' una variabile che contiene un indirizzo in memoria. Se questo indirizzo non è valido, allora la tua applicazione andrà in crash con l'errore segmentation fault. Ogni variabile ha una sua vita/durata che è determinata dal blocco in cui si trova (qualcosa delimitato da parentesi graffe). Se definisci una variabile all'interno di una funzione, questa variabile non esisterà più una volta che l'esecuzione della funzione è terminata. Il corrispondente indirizzo di memoria sarà quindi invalido e accedervi porta ad un crash del programma come è successo nel tuo caso.

Quando passi un array ad una funzione o lo restituisci da essa, l'array diventa un puntatore al suo primo elemento. La vita della variabile non viene però incrementata. L'array terminerà di esistere in ogni caso alla fine del blocco di codice che lo contiene e quindi il puntatore che restituisci sarà invalido.

L'allocazione dinamica della memoria permette di avere blocchi di memoria che hanno un vita più lunga del blocco che li contiene. La durata di questa memoria parte da quella che viene chiamata "allocazione" (la riga con new che non capisci) e la sua deallocazione (la riga con delete). Se non puoi usare tale funzionalità del linguaggio allora l'unica possibilità è quella di usare la funzione solo per l'inizializzazione dei valori e non per la creazione della variabile.

Qualcosa come il seguente (nota che rimane il commento sul fatto che non è standard):
Codice:
#include <iostream>

void costruzione(float *a, int i, int v)
{
    for (int x = 0; x < i; x++) {
        std::cout << "Inserire la componente numero " << x + 1 << " del vettore numero " << v << std::endl;
        std::cin >> a[x];
    }
}

int main ()
{
    std::cout << "Inserire la dimensione del vettore" << std::endl;
   
    int i;
    std::cin >> i;
   
    float a[i];
    costruzione(a, i, 1);

    float b[i];
    costruzione(b, i, 2);

    for (int j = 0; j < i; j++) {
        std::cout << a[i] + b[i] << std::endl;
    }
}
apatriarca
Moderatore
Moderatore
 
Messaggio: 5203 di 10435
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C++] Funzioni che restituiscono array

Messaggioda mklplo » 03/03/2019, 15:51

Ok, grazie nuovamente. Quindi se ho capito bene, se nel primo programma avvessi provato a richiamare il puntatore dopo il "delete" avrei avuto un errore perché sarebbe finita la sua durata giusto?
Grazie anche per il secondo programma, non avrei mai pensato a un modo del genere di usare le procedure.
mklplo
Advanced Member
Advanced Member
 
Messaggio: 814 di 2272
Iscritto il: 21/02/2016, 16:05

Re: [C++] Funzioni che restituiscono array

Messaggioda apatriarca » 03/03/2019, 15:59

Esatto. Anche se a volte la memoria viene riutilizzata e invece di un crash ottieni valori errati. Ma l'idea è quella.
apatriarca
Moderatore
Moderatore
 
Messaggio: 5204 di 10435
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C++] Funzioni che restituiscono array

Messaggioda mklplo » 03/03/2019, 20:19

Ok, grazie nuovamente.
mklplo
Advanced Member
Advanced Member
 
Messaggio: 815 di 2272
Iscritto il: 21/02/2016, 16:05


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite