Problema con funzione

di Anonimizzato8637 il
5 risposte
Salve a tutti. Ho un problemino su questo programma: in pratica la funzione TerzaCoordinata dovrebbe restituirmi tutti i nomi dei punti in cui la terza coordinata sia maggiore di un valore dato. Il problema è che mi mostra solo l'ultimo di questi nomi ripetuto n volte. Ho capito pure il perchè: in pratica il puntatore alla struttura non avanza, e mi scrive sempre la stessa cosa. Ho provato con p++ ma non funziona lo stesso. Il puntatore alla struttura dovrebbe iniziare dal primo elemento ma non so come scriverglielo al compilatore. Perchè in teoria scrivere Punto3D *p=new Punto3D[n] l'operatore new mi riestituisce l'indirizzo di memoria del primo elemento allocato nell'heap. Ma riscrivendolo commetto un errore e comunque non funziona. Come ovviare? Grazie. Il codice è il seguente:

#include <iostream>

using namespace std;

struct Punto3D
{
    double x, y, z;
    char *nome;
};

void LeggePunto3D (Punto3D *p, int); // Prototipi
void LeggeVettoriPunti3D (Punto3D *p, int);
void TerzaCoordinata (Punto3D *p, int, int);

int main ()
{
    
    int n;
    cout << "Inserisci il numero di punti: ";
    cin >> n;
    
    Punto3D *p; // Puntatore alla struttura Punto3D
    
    p=new Punto3D[n]; //Allocazione dinamica di un array di n strutture
    p->nome=new char[15]; // ..e di un array di caratteri
    
    LeggePunto3D (p,n); // Funzione che prende i dati di input
    LeggeVettoriPunti3D (p,n); /*Funzione che restituisce gli indirizzi di ciascun elemento
                                  dell'array*/
    cout << "Inserisci un valore: ";
    int valore;
    cin >> valore;
    
    TerzaCoordinata (p,n,valore);
    
    delete [] p; // Deallocazione finale. Ad ogni new deve corrispondere un delete
    delete [] p->nome;
    
    cout << endl << endl;   
    system ("PAUSE");
    return 0;
}

void LeggePunto3D (Punto3D *p, int n)
{
     for (int i=0; i<n; i++)
     {
     cout << "Inserisci le coordinate x,y e z: ";
     cin >> p->x >> p->y >> p->z;
     cout << "Inserisci il nome: ";
     cin.sync();
     cin.getline (p->nome,15);
     }
}

void LeggeVettoriPunti3D (Punto3D *p, int n)
{
     for (int i=0; i<n; i++)
     cout << "Indirizzo dell'elemento " << i << " : " << &p[i] << endl;
}

void TerzaCoordinata (Punto3D *p, int n, int valoredato)
{
     for (int i=0; i<n; i++)
     {
     if (p->z > valoredato)
     cout << p->nome << endl;
     }
}

5 Risposte

  • Primo errore
    
    void LeggePunto3D (Punto3D *p, int n)
    {
         for (int i=0; i<n; i++)
         {
         cout << "Inserisci le coordinate x,y e z: ";
         cin >> p[i].x >> p[i].y >> p[i].z;
         cout << "Inserisci il nome: ";
         cin.sync();
         cin.getline (p[i].nome,15);
         }
    }
    
    secondo errore
    
    void TerzaCoordinata (Punto3D *p, int n, int valoredato)
    {
         for (int i=0; i<n; i++)
         {
         if (p[i].z > valoredato)
         cout << p[i].nome << endl;
         }
    }
    
    Terzo errore
    
    for(i = 0; i < n; i++)
        delete [] p[i].nome;
    
    delete [] p; // Deallocazione finale. Ad ogni new deve corrispondere un delete
    
  • Quarto errore
    
    p=new Punto3D[n]; //Allocazione dinamica di un array di n strutture
    for(i = 0; i < n; i++)
          p[i].nome=new char[15]; // ..e di un array di caratteri
    
  • Grazie skynet per avermi fatto vedere gli errori. In effetti l'accesso ai campi di una struttura allocata dinamicamente con new si fa per indice. Anche se non mi è chiaro il perchè. Cioè se io avessi dichiarato un puntatore p di tipo semplice (ad esempio Punto3D *p) avrei potuto accedere ai campi della struttura con l'operatore freccia ->. Mentre se uso il new (alloco dinamicamente la memoria) si fa per indice p. Come mai? Il new non è simile all'& di assegnamento a un puntatore, con la differenza che il new assegna un area dell'heap e l'& un'area qualsiasi? Aspetto cordiali delucidazioni. Grazie.
  • Il new [] alloca un array di elementi e ti ritorna un puntatore al primo elemento. Fare p oppure p++ è la stessa cosa ma con p++ perdi l'elemento precedente.
    Se tu avessi una varibile p allocata in modo statico come faresti:
    
    Punto3D p[10];
    
    ogni elemento lo raggiungi con p. La stessa cosa fa anche new, ne + e ne meno.
    il new lo puoi paragonare al malloc di C e non assegna ma notifica dove si trova l'inizio dell'area di memoria allocata.
    Un esempio valido è anche questo.
    
    new Punto3D[n];
    
    non tiesce nessun errore, semplicemente te ne freghi dove ha allocato new (causando un memory leak ma questo è un altro discorso) e non puoi + recuperare quella memoria allocata.
  • Ora è chiaro skynet.
Devi accedere o registrarti per scrivere nel forum
5 risposte