Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2002
    Messaggi
    26

    [C++] puntatori- spiegazioni

    ciao. sto studiando c++ per l'università. vorrei chiedervi alcune domande sui puntatori, perchè non mi sono proprio chiari dal tutto.

    1. se faccio (int *a) inizializzo un nuovo puntatore; a cosa punta però questo puntatore. penso a un valore a caso (forse a NULL?). però ho visto che se inizializzo solo il puntatore (e nessun'altra variabile) punta a un indirizzo molto vicino al suo (cioè facendo cout<<a , cout<<&a risultano due indirizzi molto vicini fra loro). se però prima della variabile puntatore ne inizializzo un'altra (es. int b) il puntatore punta all'indirizzo 0000. come mai?

    2. faccio (int a, int b): sono due variabili non puntatore ma normali. vedendo il loro indirizzo in cui sono state posizionate, ha un indirizzo piu basso la variabile inizializzata dopo (in questo caso b). come mai?? (es &a=x1000, &b=x999)

    3. mi è stato spiegato che gli array possono essere di due tipi: statici o dinamici. allora i primi sono quelli inizializzati normalmente (es. int a[10]), mentre i secondi inizializzati per mezzo di puntatori (es. int *a, a=new int[10]). poi mi è stato detto che il nome che diamo all'array (in questo caso a) corrisponde all'indirizzo in cui l'array è posizionato. ma questo accade solo per gli array dinamici, vero? cioè per vedere l'indirizzo di a per un array statico deve fare cout<<&a (oppure cout<<&a[2] per vedere l'indirizzo ad esempio del 3 elemento). invece per gli array dinamici per vedere l'indirizzo basta fare cout<<a (che quindi dovrebbe corrispondere a cout<<&a[0]). perchè se invece facciamo cout<<&a vedo l'indirizzo non del primo elemento dell'array, ma l'indirizzo del puntatore a (che punta all'array creato con l'istruzione new)

    4. inizializzo un puntatore con (int *pa); poi lo faccio puntare ad un intero mediante l'istruzione (pa=new int). quindi cosi automaticamente il puntatore pa punta al nuovo intero allocato? ma quindi è la stessa cosa di fare (int *pa, int a, pa=&a)?
    ma se faccio (cout<<pa) viene stampato l'indirizzo del puntatore pa o dell'intero allocato? io penso l'intero.

    5. inizializzo un puntatore con (int *pa); poi lo faccio puntare ad un intero mediante l'istruzione (pa=new int). poi tolgo l'allocazione del nuovo intero mediante l'istruzione (delete). a cosa punta ora il puntatore?

    spero mi abbiate sopportato in tutta questa serie di lunghe domande e che mi abbiate capito e che potete rispondermi.
    se ho sbagliato in qualche ragionamento sarei grato se mi rispondete e mi correggete.
    grazie in anticipo.

    ciao edoardo.

  2. #2
    1. 2. 5. Le risposte a questi punti sono specifiche del compilatore. E` opera del compilatore (o del sistema operativo) l`allocazione delle variabili, quindi non c`e` un criterio universalmente valido.

    3. Anche il fatto degli array statici o dinamici e` una convenzione propria del linguaggio. In realta` sono entrambi puntatori, solo che se il compilatore nota che un array e` stato dichiarato con una certa sintassi (int array[ 10 ]), ti segnalera` degli errori non appena tenterai di modificare il valore di 'array' che e` un puntatore, ma costante. A basso livello array "statici" e "dinamici" sono identici, le restrizioni su quelli statici le stabilisce il linguaggio stesso (e di conseguenza il compilatore). Fondamentalmente i cosiddetti array dinamici sono dei puntatori non costanti.
    Stesso discorso a livello di sintassi, quindi per vedere l`indirizzo di un array qualsiasi farai in ogni caso:

    codice:
    cout << a;
    4. Con 'new' si suppone che tu voglia in futuro poter deallocare la memoria allocata; se invece dichiari una variabile e la fai puntare da un puntatore significa che quella memoria (quella della variabile) sara` occupata "staticamente" fino alla fine del programma (o nello scope adeguato). In tema di sintassi:

    ma se faccio (cout<<pa) viene stampato l'indirizzo del puntatore pa o dell'intero allocato? io penso l'intero
    Sbagli. 'pa' e` un puntatore, quindi viene stampato l`indirizzo. Per stampare l`intero invece devi dereferenziare:

    codice:
    cout << *pa;
    Ti saluto, sperando sempre di essere stato chiaro. Per ogni dubbio posta qui.

    Ciao.

  3. #3
    Come sempre sono d'accordo con r0x.

    Sul punto 5 vorrei aggiungere che nel 99% dei casi puntera' ad un'area di memoria non valida. Dopo un delete e' sovente meglio assegnare il valore NULL al puntatore, per evitare di fare confusione (e soprattutto di ri-deletarlo, con effetti disastrosi), infatti delete (a meno di implemetazioni stravaganti del compilatore) non modifica il valore contenuto nel puntatore, in quanto in C/C++ tutti i passaggi di variabile sono per valore (salvo diversa ed esplicita dichiarazione del programmatore). Quindi il tuo puntatore passato alla delete, consente alla delete di accedere alla memoria puntata dal tuo puntatore, non al puntatore stesso, in breve, se cout << p; stampa 100, allora delete p; cout << p; stampa 100, solo che 100 adesso non e' piu' valido.

  4. #4
    Utente di HTML.it
    Registrato dal
    Sep 2002
    Messaggi
    26
    innanzitutto grazie a chi mi ha risposto. poi vorrei porvi alcune ulteriori chiarimenti sulle domande poste, dato che non ho capito bene tutto. grazie, sperando che abbiate ancora un po di pazienza

    allora domanda 1 e 2 sono chiare.

    riguardo la 3; se ho un array allocato in modo dinamico(lo chiamo ad esempio a) (cioè attraverso un puntatore) se faccio (cout<<a) viene stampato l'indirizzo del primo elemento dell'array. vero? (e cout<<a è equivalente a &a[0]). giusto?
    ma se l'array è stato inizializzato in modo statico (int array[n]) per vedere l'indirizzo del primo elemento è possibile fare (cout<<a)?? non bisogna fare per forza (cout<<&a[0])?

    riguardo la 4: ok la differenza l'ho capita. l'altra domanda posta mi sono sbagliato; se faccio (int *a, a= new int, cout<<a) viene stampato l'indirizzo in memoria del nuovo intero allocato. vero? se invece voglio conoscere l'indirizzo a cui è stato messo in memoria il puntatore devo fare (cout<<&a). giusto?

    ultima domanda (5): ma se dopo aver allocato una nuova zona con new e poi la tolgo con delete, l'istruzione delete non elimina la zona di memoria precedentemente allocata per cosi consentire l'allocazione di nuove variabili?
    però il puntatore punta ugualmente alla stessa zona di memoria (cioè quella dove prima si aveva allocato con new qualcosa e invece ora lo si è tolto)? quindi punta alla stessa zona, ma non si sa cosa è contenuta in essa?

    spero mi abbiate capito e siate in grado (o meglio abbiate la pazienza) di rispondermi.

    grazie.

    ciao edoardo

  5. #5
    Ciao

    risposta 3)
    Si cout << a , cout << &a[0] sono due notazioni equivalenti, anche se la prima è molto più elegante.
    Le notazioni precedenti, valgono anche nel caso di un vettore allocato staticamente, visto che il C++ tratta i vettori sostanzialmente come puntatori.

    risposta 4)
    Se a è un puntatore ad una locazione di memoria dinamica.
    cout << a; // stampa l'indirizzo di memoria al quale punta a.
    cout << &a; // stampa la locazione di memoria in cui è allocato il puntatore.

    risposta 6)
    l'operatore delete serve per deallocare le locazioni di memoria heap (zona di memoria dinamica) impegnate mediante l'utilizzo dell'operatore new. L'operazione di deallocazione del delete è obbligatoria ogni qual volta termina l'utilizzo della parte di memoria heap impegnata con il new, altrimenti si corre il rischio di mandare in crash il sistema (colui che alloca, si occupa anche della deallocazione); questa operazione non fa altro che rendere disponibile la memoria in precedenza utilizzata affinchè possa essere sfruttata da altri processi. Una volta deallocato il puntatore esso punta a 0.

    Spero di esserti stato di aiuto.
    A presto

    Maximo
    La luce è più veloce del suono,ecco xchè alcune persone sembrano brillanti fino a quando non parlano


  6. #6
    Se a è un puntatore ad una locazione di memoria dinamica.
    Basta che sia un puntatore.

    L'operazione di deallocazione del delete è obbligatoria ogni qual volta termina l'utilizzo della parte di memoria heap impegnata con il new, altrimenti si corre il rischio di mandare in crash il sistema
    Nell`esempio di Windows ogni programma ha un proprio heap privato, e all'uscita del programma tutto l`heap viene deallocato, senza memory leaks. Il problema e` che tale heap e` limitato, e i memory leaks accumulati rimangono fino alla fine del programma, ma non oltre. Altri sistemi operativi non so come si comportano.

    Una volta deallocato il puntatore esso punta a 0.
    Beh, non e` detto. Leggi il post di Andrea.

    BAI!

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2002
    Messaggi
    26
    ciao,
    grazie a tutti quelli che mi hanno risposto.
    mi rimangono ancora un po di dubbi sulla domanda 5, in particolar modo cosa succede dopo aver fatto delete.
    da quanto capito con delete la zona di memoria precedentemente allocata viene deallocata, cioè viene liberata e puo essere poi allocata nuovamente. quindi a questo punto il puntatore che prima puntava a questa zona di memoria o punta a null oppure alla stessa zona di memoria, anche se non si sa cosa c'è ora in questa zona, dato che con delete immagino venga in qualche modo cancellata (si dovrebbero trovare cosi dei valori a caso).
    nel caso sbagli in qualcosa, se potete rispondermi sono felice.
    ciao edoardo.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.