Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    [C] errore nella gestione di un array

    ciao ragazzi prendendo spunto da un libro ho creato un vettore dinamico di 10 elementi e ho pensato di gestirlo come in matematica si fa con le matrici (cioè con elementi che vanno da 1 a n )


    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    
    
    /* esercizio 2 */
    
    
    int main ()
    
    { 
    	int *m ;
    	int n = 10 ;
    	int i ;
    
    	m = (int*) malloc (sizeof (int) * n ) ;
    	m-- ; /* non capisco questo pezzo */
    
    	for ( i = 1 ; i <= 10 ; i++ )
    		m[i] = 1 + rand () % 10 ;
    
    	for (i = 1 ; i <= 10  ; i++ )
    		fprintf(stdout ,"%d\n" ,  m[i] ) ;
    
    
    	free(m) ;
    
    	system ("PAUSE") ;
    
    	return 0 ;
    
    
    }

    dopo aver allocato lo spazio nella memoria con Malloc ho usato
    codice:
    m-- ;
    per cambiare il primo elemento da 0 a 1 (prendendo spunto dal suddetto libro)




    ora il programma mi genera un errore nell' HEAP ;

    ho due domande da porvi :
    1) in che modo "m-- " riesce a "slittare" gli elementi da "0-9" a "1-10" ,
    e
    2) da dove salta fuori quell'errore

    grazie

  2. #2
    Diciamo che il libro ti risulta un po ostico. Se questa è la spiegazione di come funziona un array un po' di cose sono superflue:

    1) è inutile fare una malloc (per dieci numeri andare a ottimizzare la gestione dello spazio mi sembra eccessivo). E se questa fosse la parte dinamica del tuo programma non ne vedo l'utilità
    2) è inutile usare un fprintf, va benissimo il solo printf.

    Allora siccome m diventa un puntatore (che puoi visualizzare come una casella dell'array), prima ti abbassa m di uno (se m puntava 22, ti fa puntare 21) poi fa partire il for con i che parte da 1. Questo comporta il fatto che m non parta da 21, ma da 22.

    Quindi il tuo codice sarebbe molto più comodo così:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main ()
    
    { 
    	int m[10], i ;
    
        for(i=0;i<10;i++)
            /*metti quello che vuoi*/
        
        for(i=0;i<10;i++)
            printf("%i", i);
    
    	system ("PAUSE") ;
    
    	return 0 ;
    }

  3. #3
    ciao quello che non riesco a capire ( al di la della comodità ) ( è solo un esercizio ) è come
    il puntatore m si abbassi di 1

    cioè :
    scrivendo m-- , m non diventa -1 ?
    cioè m è equivalente a &m[0] no?

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Dopo l'allocazione dinamica, il puntatore m avrà un certo valore, diciamo 0x1234. Viene dunque decrementato di 1, il che significa che il suo valore viene decrementato di tanti byte quanti sono quelli che costituiscono il tipo di dato a cui il puntatore punta: se m è un puntatore a int e un int è su 4 byte, il valore di m una volta decrementato sarà 0x1230.
    A quel punto nei due for successivi utilizzi gli indici a partire da 1 fino a 10 (anziché 0-9) perché scrivendo m[1] di fatto stai accedendo alla locazione di memoria successiva a quella dell'indirizzo base, ma visto che questo era stato decrementato di una posizione allora stai accedendo proprio alla prima componente dell'array allocato, utilizzando però l'indice 1 anziché 0 come sarebbe normalmente.
    Prova a stampare un po' i valori degli indirizzi per renderti conto di tutto questo.
    Quello che mi chiedo è come possa non darti un errore runtime l'istruzione free(m) visto che m, essendo stato decrementato, non è il valore originario dell'indirizzo al partire dal quale è stata allocata la memoria... dovresti sostituire quell'istruzione con free(m+1); o simili.
    every day above ground is a good one

  5. #5
    Originariamente inviato da YuYevon
    Dopo l'allocazione dinamica, il puntatore m avrà un certo valore, diciamo 0x1234. Viene dunque decrementato di 1, il che significa che il suo valore viene decrementato di tanti byte quanti sono quelli che costituiscono il tipo di dato a cui il puntatore punta: se m è un puntatore a int e un int è su 4 byte, il valore di m una volta decrementato sarà 0x1230.
    A quel punto nei due for successivi utilizzi gli indici a partire da 1 fino a 10 (anziché 0-9) perché scrivendo m[1] di fatto stai accedendo alla locazione di memoria successiva a quella dell'indirizzo base, ma visto che questo era stato decrementato di una posizione allora stai accedendo proprio alla prima componente dell'array allocato, utilizzando però l'indice 1 anziché 0 come sarebbe normalmente.
    Prova a stampare un po' i valori degli indirizzi per renderti conto di tutto questo.
    Quello che mi chiedo è come possa non darti un errore runtime l'istruzione free(m) visto che m, essendo stato decrementato, non è il valore originario dell'indirizzo al partire dal quale è stata allocata la memoria... dovresti sostituire quell'istruzione con free(m+1); o simili.

    perchè l'istruzione corretta è free (m+1)



    ero convinto che con m-- decrementassi di 1 "componente" nel vettore , invece si tratta di byte ..
    aritmetica dei puntatori..

    scusa ma in questo modo

    dire m-- ed m[0]-- è la stessa identica cosa no?
    il puntatore m punta ad un area di memoria consecutiva di 10 "int" e il primo elemento è m[0] ;
    ponendo m-- dovrebbe puntare a "qualcosa" prima dell elemento m [0] no?

    grazie!

  6. #6
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Originariamente inviato da toni00c
    perchè l'istruzione corretta è free (m+1)
    Ecco appunto, o anche free(++m);



    scusa ma in questo modo

    dire m-- ed m[0]-- è la stessa identica cosa no?
    No, con m-- decrementi il valore del puntatore mentre con m[0]-- decrementi la prima componente dell'array (appunto quella di indice 0) che è cosa completamente diversa.

    il puntatore m punta ad un area di memoria consecutiva di 10 "int" e il primo elemento è m[0] ;
    ponendo m-- dovrebbe puntare a "qualcosa" prima dell elemento m [0] no?
    Sì esatto, di fatto è come se puntasse a m[-1] con il valore originario di m. Dato però che tu utilizzi direttamente l'indice 1 nei due for, accedi al secondo elemento a partire dall'indirizzo m decrementato, che corrisponde quindi al primo del vettore.
    every day above ground is a good one

  7. #7
    Allora siccome m diventa un puntatore (che puoi visualizzare come una casella dell'array), prima ti abbassa m di uno (se m puntava 22, ti fa puntare 21) poi fa partire il for con i che parte da 1. Questo comporta il fatto che m non parta da 21, ma da 22.
    Ti avevo spiegato in maniera molto semplice cosa avveniva e poi suggerito un metodo diverso

  8. #8
    Originariamente inviato da _Alfabetagamma_
    Ti avevo spiegato in maniera molto semplice cosa avveniva e poi suggerito un metodo diverso
    ti ringrazio molto , sto facendo un po di fatica !
    sbaglio o in questo forum ci sono diversi studenti?
    lo sei anche tu?

  9. #9
    Si si, io sto studiando ing informatica, sono al primo anno, quindi non è che posso aiutare moltissimo, però se posso, mi fa piacere dare una mano

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.