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

    problema array con C++

    Salve a tutti, questo è il mio primo post.
    Avrei un piccolo problema con gli array (vettori) nel C++.
    Dunque ora cerco di spiegare bene con un esempio perchè così si capisce meglio.

    codice:
     
    #include <iostream>
    using namespace std;
    
    int main () {
        const int dim = 4;
        int misure[dim];
    
        int muse[5] = {4, 6, 3, 7, 8};
    
        misure[0]= 45;
        misure[1]= 37;
        misure[2]= 29;
        misure[3]= 56;
        * 
        cout << misure[2] << endl;
        cout << muse[3] << endl;
        **
            }
        
    return 0;
    }
    Questo codice mi viene compilato ed eseguito correttamente. (Correggetemi se sbaglio).
    SE invece aggiungo nel codice questa porzione di codice:

    *misure[7]= 35;

    **cout << misure[7] << endl;

    Il programma (DEV C++) mi compila correttamente il codice e me lo esegue anche correttamente!!! Cioè mi stampa a video il valore di "misure[7]" anche se nell'intestazione c'è scritto chiaramente che il vettore ha dimensione 4.
    Lo stesso vale anche con il secondo vettore dichiarato. Per non creare confusione non aggiungo altro, ma se nel codice scrivessi lo stesso errore per il vettore muse, come per il vettore misure, il programma compila ed esegue.

    Quindi:
    Sapendo che a livello teorico quello che ho scritto con gli asterischi è un errore, mi preme sapere perchè viene compilato cmq il codice.
    E' il programma che uso che ha dei limiti e permette questi erroracci, oppure c'è qualcosa sotto, tipo che si può fare una cosa del genere in C++?


    2° domandina:
    Da quello che so un array deve essere sempre definito con una costante. Anche se sia variabile (come nell'esempio sopra), si imposta a costante.
    Perchè allora se compilo un programma con dimensione di array solamente definita come:
    int dim;
    int array[dim]

    senza porre come costante la variabile dim, il programma mi si compila ed esegue lo stesso?
    A mia vista si esegue correttamente. Perchè?
    Sempre errore del compilatore?
    Oppure è possibile che un array sia definito come ho scritto qualche riga sopra (cioè con variabile non costante)?


    Ringrazio sentitamente chi riuscirà a chiarirmi questi dubbi amletici
    PS: spiegate anche le motivazioni Grazie!!!

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Ne C ne C++ controllano un eventuale sforamento dei limiti massimi dell'array, e cosa succede, quando avviene, ricade nel "comportamento indefinito" (undefined behaviour).

    Da quello che so un array deve essere sempre definito con una costante. Anche se sia variabile (come nell'esempio sopra), si imposta a costante.
    Corretto.
    Perchè allora se compilo un programma con dimensione di array solamente definita come:
    int dim;
    int array[dim]
    senza porre come costante la variabile dim, il programma mi si compila ed esegue lo stesso?
    A mia vista si esegue correttamente. Perchè?
    Perché è una porcheria introdotta nel gcc e poi ratificata nello standard ISO C99 che prevede i VLA ( variable length array ). A quanto ne so funziona solo su gcc e i vari porting, ma non su altri compilatori. Il C++ non prevede questa ciofeca e giustamente si rifiuta di compilare se gliela proponi. Attualmente, poi, DEVC++ è un insulto, non un compilatore.
    Il mio consiglio è passare a VC++ Express o ( se non ti piace M$ ) a CodeBlocks ( di cui trovi vari porting).
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3

    Re: problema array con C++

    Originariamente inviato da programfile
    Quindi:
    Sapendo che a livello teorico quello che ho scritto con gli asterischi è un errore, mi preme sapere perchè viene compilato cmq il codice.
    E' il programma che uso che ha dei limiti e permette questi erroracci, oppure c'è qualcosa sotto, tipo che si può fare una cosa del genere in C++?
    Lo standard C++ dice che sforare da un array è "undefined behavior"; questo significa che potrebbe funzionare tutto, potrebbe andare in crash il programma o potrebbero atterrare gli alieni e deportarci tutti su alpha centauri.

    Nel mondo reale, la questione è la seguente: quando specifichi le dimensioni di un array, stai semplicemente dicendo al compilatore quanto spazio riservare per l'array in questione. Al momento di accedere agli elementi non è effettuato alcun controllo sull'indice inserito, fondamentalmente per ragioni di efficienza (lo standard dice che l'accesso ad un array come array[indice] deve essere equivalente all'espressione *(array+indice), che, essendo una semplice somma di puntatori, non prevede controlli di alcun genere).

    Questo significa che, andando oltre le dimensioni dell'array, nessuno ti dice niente, ma stai andando a scrivere in memoria che non è quella riservata all'array. Se sei fortunato il programma va in crash subito (questo accade in particolare se l'area immediatamente successiva al tuo array è memoria protetta, cosa praticamente impossibile per le variabili locali), altrimenti vai a sovrascrivere altre variabili (in genere situate nella procedura corrente per le variabili locali), in cui probabilmente ti ritroverai valori "strani".

    Altrimenti, potresti andare a sovrascrivere l'indirizzo di ritorno della procedura corrente, per cui, al momento di ritornare, la procedura corrente cercherà di tornare ad un indirizzo che non c'entra un tubo, causando il crash del programma o (peggio) l'esecuzione di codice che non c'entra niente.

    In ogni caso, tutto questo è male. Stai sempre attento a non sforare dagli array, molti bachi di sicurezza derivano da problemi di questo genere.
    2° domandina:
    Da quello che so un array deve essere sempre definito con una costante. Anche se sia variabile (come nell'esempio sopra), si imposta a costante.
    Perchè allora se compilo un programma con dimensione di array solamente definita come:
    int dim;
    int array[dim]

    senza porre come costante la variabile dim, il programma mi si compila ed esegue lo stesso?
    A mia vista si esegue correttamente. Perchè?
    Sempre errore del compilatore?
    Oppure è possibile che un array sia definito come ho scritto qualche riga sopra (cioè con variabile non costante)?
    È un'estensione non-standard del compilatore gcc. Nel C99 gli array allocati sullo stack ma a dimensione variabile (VLA) sono stati standardizzati, mentre nel C++ non sono stati accettati per diverse ragioni. In linea di massima in C++ se serve un array le cui dimensioni sono note solo a runtime si usa l'heap (con gli operatori new e delete).
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    Originariamente inviato da shodan
    Ne C ne C++ controllano un eventuale sforamento dei limiti massimi dell'array, e cosa succede, quando avviene, ricade nel "comportamento indefinito" (undefined behaviour).
    Quindi l'unico metodo è controllare e ricontrollare mille volte il codice perchè solo io (o cmq il programmatore) può controllare che tutto sia giusto comprese le dimensioni e i valori dell'array, altrimenti tutto mi si compila come se niente fosse. Giusto?
    Perchè quando lo compilo con la dimensione sbagliata non è che mi restituisce un valore random, no, mi restituisce il valore che ho definito io anche se fuori dall'array!
    Quindi per questo problema è colpa del compilatore oppure è solamente il linguaggio che non controlla?

    Originariamente inviato da shodan
    Perché è una porcheria introdotta nel gcc e poi ratificata nello standard ISO C99 che prevede i VLA ( variable length array ). A quanto ne so funziona solo su gcc e i vari porting, ma non su altri compilatori. Il C++ non prevede questa ciofeca e giustamente si rifiuta di compilare se gliela proponi. Attualmente, poi, DEVC++ è un insulto, non un compilatore.
    Il mio consiglio è passare a VC++ Express o ( se non ti piace M$ ) a CodeBlocks ( di cui trovi vari porting).
    In questo secondo caso quindi è solo colpa del compilatore? Se compilassi con altri programmi questi mi si rifiuterebbero di compilare ciò che ho scritto sopra?

    I programmi che mi citi sono gratis o a pagamento? (scusate l'ignoranza! )
    Grazie mille per la risposta!!!

  5. #5
    Originariamente inviato da programfile
    Quindi l'unico metodo è controllare e ricontrollare mille volte il codice perchè solo io (o cmq il programmatore) può controllare che tutto sia giusto comprese le dimensioni e i valori dell'array, altrimenti tutto mi si compila come se niente fosse. Giusto?
    Perchè quando lo compilo con la dimensione sbagliata non è che mi restituisce un valore random, no, mi restituisce il valore che ho definito io anche se fuori dall'array!
    Non necessariamente. Se poi scrivi nella memoria dove hai scritto questo valore in maniera "corretta" ti ritrovi un altro valore.
    Quindi per questo problema è colpa del compilatore oppure è solamente il linguaggio che non controlla?
    È undefined behavior definito a livello di linguaggio.

    In ogni caso, in generale puoi utilizzare la classe template std::vector (parte della libreria standard) e usare il metodo at per accedere agli elementi, che controlla sempre l'indice passato.

    In questo secondo caso quindi è solo colpa del compilatore? Se compilassi con altri programmi questi mi si rifiuterebbero di compilare ciò che ho scritto sopra?
    No; tuttavia, se sfori un array in modo così palese da sforare anche dallo stack frame (sovrascrivendo l'indirizzo di ritorno) i compilatori moderni fanno sì che il tuo programma si arresti con un errore invece di andare avanti in uno stato incoerente (è una protezione contro gli attacchi di stack-smashing).
    I programmi che mi citi sono gratis o a pagamento? (scusate l'ignoranza! )
    Grazie mille per la risposta!!!
    Sono entrambi gratis. Nota comunque che Code::Blocks e Dev-C++ sono due IDE diverse, il compilatore che ci sta sotto è lo stesso (MinGW, il porting per Windows di g++); tuttavia dato che Dev-C++ ha cessato lo sviluppo diversi anni fa ti ritrovi una versione piuttosto vecchia di MinGW, mentre con Code::Blocks hai le versioni più recenti.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Un altro compilatore gratis, compatibile con Codeblocks, è Borland C++ 5.5.1 (è da qualche parte nel sito di Embarcadero), ma non hai il debugger.
    E' comunque una buona alternativa per farsi le ossa.

    Diciamo che va bene tutto tranne DEVC++
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  7. #7
    Originariamente inviato da MItaly
    In ogni caso, in generale puoi utilizzare la classe template std::vector (parte della libreria standard) e usare il metodo at per accedere agli elementi, che controlla sempre l'indice passato.
    Non l'ho mai usata... come funziona?

    Originariamente inviato da MItaly
    Sono entrambi gratis. Nota comunque che Code::Blocks e Dev-C++ sono due IDE diverse, il compilatore che ci sta sotto è lo stesso (MinGW, il porting per Windows di g++); tuttavia dato che Dev-C++ ha cessato lo sviluppo diversi anni fa ti ritrovi una versione piuttosto vecchia di MinGW, mentre con Code::Blocks hai le versioni più recenti.
    Quindi...DEV è un pò vecchiotto...
    Bhe allora mi sa che cambio compilatore!
    Volevo chiedere... è possibile avere dei link dove scaricare questi due software visto che sono gratis oppure no?
    Se vado contro il regolamento con questa richiesta chiedo anticipatamente scusa.

    MItaly grazie per le risposte esaustive che mi hai fornito


    Originariamente inviato da shodan
    Un altro compilatore gratis, compatibile con Codeblocks, è Borland C++ 5.5.1 (è da qualche parte nel sito di Embarcadero), ma non hai il debugger.
    E' comunque una buona alternativa per farsi le ossa.

    Diciamo che va bene tutto tranne DEVC++
    Borland? Ma...ehm..scusatemi l'ignoranza, ma questo non era a pagamento?

  8. #8
    Originariamente inviato da programfile
    Non l'ho mai usata... come funziona?
    Ti rimando alla sua documentazione di riferimento, nelle pagine dei vari metodi ci sono anche un po' di esempi.
    Quindi...DEV è un pò vecchiotto...
    Bhe allora mi sa che cambio compilatore!
    Volevo chiedere... è possibile avere dei link dove scaricare questi due software visto che sono gratis oppure no?
    Se vado contro il regolamento con questa richiesta chiedo anticipatamente scusa.
    Microsoft Visual C++ Express Edition (quando crei un nuovo progetto scegli progetto console nativo win32)
    Code::Blocks (mi raccomando scegli il download con MinGW incluso)
    Ho sentito parlare bene anche di CodeLite (download); nota che anche lui di base usa come compilatore MinGW, per cui dal punto di vista del compilatore usato non differisce da Code::Blocks.
    MItaly grazie per le risposte esaustive che mi hai fornito
    Non c'è di che.
    Borland? Ma...ehm..scusatemi l'ignoranza, ma questo non era a pagamento?
    Il compilatore e basta è gratuito; lo puoi usare in abbinata ad un editor qualunque e alla linea di comando o a IDE come Code::Blocks (che supportano diversi compilatori).
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Originariamente inviato da MItaly
    Microsoft Visual C++ Express Edition (quando crei un nuovo progetto scegli progetto console nativo win32)
    Code::Blocks (mi raccomando scegli il download con MinGW incluso)
    Ho sentito parlare bene anche di CodeLite (download); nota che anche lui di base usa come compilatore MinGW, per cui dal punto di vista del compilatore usato non differisce da Code::Blocks.

    Il compilatore e basta è gratuito; lo puoi usare in abbinata ad un editor qualunque e alla linea di comando o a IDE come Code::Blocks (che supportano diversi compilatori).
    Grazie mille!!
    Bene allora provo questi programmi
    Se poi ho problemi posto ancora!!!
    Grazie ancora!!!

  10. #10
    Amaro C++, il gusto pieno dell'undefined behavior.

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.