AldoBaldo (Member)
Guru
Messaggi: 699
Iscritto: 08/01/2015
|
Buongiorno.
Oggi vi secco con una domanda che nasce dai dubbi improvvisi d'una persona che pratica una materia da autodidatta della domenica, senza avere solide basi teoriche. Se scrivo sciocchezze o banalità siate pazienti.
Per anni ho scritto cose tipo:
Codice sorgente - presumibilmente C/C++ |
CLASSE_X *ptr = new CLASSE_X;
if( ptr == NULL ) return kCodiceErrore;
|
Qualche tempo fa m'è capitato di leggere, non ricordo dove, che se new fallisce non necessariamente ptr riceve NULL. Garb! Da quel momento ho iniziato a scrivere cose di questo tipo:
Codice sorgente - presumibilmente C/C++ |
CLASSE_X *ptr = NULL;
try {
ptr = new CLASSE_X;
} catch( ... ) {
return kCodiceErrore;
}
|
Ora mi prende una specie di paranoia per cui tentenno tra le due soluzioni senza riuscire a decidere una volta per tutte quale sia quella da usare. Quale delle due versioni è corretta? Se una delle due è corretta e l'altra sbagliata non ci sono se, nè ma: si usa quella corretta e basta. Ammesso che siano corrette entrambe, quale è preferibile? Si incorre in qualche rischio usando la versione sconsigliabile?
Preciso che non mi riferisco ai casi in cui CLASSE_X lancia eccezioni per errori verificatisi nella funzione creatrice, bensì ai casi in cui è proprio l'operatore new che non riesce a portare a termine il proprio compito d'allocazione (magari perché non c'è memoria sufficiente per allocare lo spazio necessario; tipo, se faccio "new int;" non c'è possibilità che fallisca alcuna funzione costruttrice, ma potrebbe non esserci spazio in memoria per allocare l'int in sè e per sè). Spero di essere riuscito a spiegarmi.
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti. |
|
nessuno (Normal User)
Guru^2
Messaggi: 6380
Iscritto: 03/01/2010
|
Lo standard C++ prevede che sia lanciata una eccezione
std::bad_alloc
se la new fallisce (anche per mancanza di memoria).
Alcune versioni di vecchi compilatori non seguivano questo standard e restituivano NULL.
Ovviamente i moderni compilatori seguono lo standard.
Ultima modifica effettuata da nessuno il 29/09/2015 alle 9:47
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità. |
|
TheDarkJuster (Member)
Guru^2
Messaggi: 1620
Iscritto: 27/09/2013
|
....a meno che tu non abbia compilato (o scaricato) un compilatore con la libreria standard compilata in modo tale da non lanciare eccezioni.....
|
|
AldoBaldo (Member)
Guru
Messaggi: 699
Iscritto: 08/01/2015
|
Innanzi tutto grazie per avermi riservato la vostra attenzione. Detto questo...
Uso sempre l'IDE Code::Blocks. Nelle impostazioni del compilatore compare "GNU GCC compiler", mentre il log di compilazione riporta, in testa alla compilazione d'ogni modulo, "mingw32-g++.exe". Non sapendo se si tratta di un compilatore moderno o di uno vetusto, dopo aver cercato "std::bad_alloc" col solito Google ho provato a mettere insieme un programmino di test.
Codice sorgente - presumibilmente C++ |
#include <stdio.h> #include <new> int main() { const size_t dimBlocco = 1048576; // 1 MB const int maxBlocchi = 4096; char *ptr = NULL; int i; printf( "Inizio allocazioni\n\n" ); for( i=0; i<maxBlocchi; ++i ) { try { ptr = new char[dimBlocco]; if( ptr == NULL ) { printf( " Allocazione n. %d, puntatore NULL.\n\n", i+1 ); break; } } catch( std::bad_alloc& err ) { printf( " Allocazione n. %d, eccezione.\n", i+1 ); printf( " Indirizzo puntato: 0x%08lX\n\n", (unsigned long) ptr ); break; } } printf( "Fine allocazioni\n\n" ); getchar(); return 0; }
|
Il programma, eseguito su un netbook con 2GB di ram, mi dà in output questa roba qui:
Codice sorgente - presumibilmente Plain Text |
Inizio allocazioni
Allocazione n. 1916, eccezione.
Indirizzo puntato: 0x7FE50020
Fine allocazioni
|
...dal che deduco che il compilatore che uso sia di quelli "moderni" e con una libreria strutturata secondo lo standard, perché tentando di allocare il 1916esimo megabyte di memoria "new" lancia l'eccezione "std::bad_alloc", come scriveva nessuno. Deduco anche che la formulazione corretta per usare "new" sia la seconda, cioè...
Codice sorgente - presumibilmente C/C++ |
CLASSE_X *ptr = NULL;
try {
ptr = new CLASSE_X;
} catch( ... ) {
return kCodiceErrore;
}
|
...dove oltre ad acchiappare "std::bad_alloc" acchiappo anche qualsiasi altro tipo d'eccezione dovesse venirgli in mente di lanciare.
Ah! La meravigliosa sensazione di poter scegliere a ragion veduta. Grazie ancora, farò tesoro.
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti. |
|
nessuno (Normal User)
Guru^2
Messaggi: 6380
Iscritto: 03/01/2010
|
Tutto ok ... solo una nota ... il fatto che il compilatore sia o meno recente dipende dalla sua versione, che non ci hai dato ...
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità. |
|
AldoBaldo (Member)
Guru
Messaggi: 699
Iscritto: 08/01/2015
|
Eh, che questione che mi poni! Cercando nella cartella di Code::Blocks=>MinGw ho trovato solo questa intestazione, in un file chiamato "README-gcc-tdm.txt":
Codice sorgente - presumibilmente Delphi |
=== TDM-GCC Compiler Suite for Windows === --- GCC 4.6 & 4.7 Series --- *** Standard MinGW 32-bit Edition *** This edition of TDM-GCC is an unofficial replacement for the official GCC binaries distributed by the MinGW project; please note the following caveats: * TDM-GCC is not formally affiliated with or endorsed by the MinGW project. * No level of support for TDM-GCC is in any way guaranteed, although a best effort is made to fix bugs as they are found or forward them to GCC Bugzilla.
|
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti. |
|
TheDarkJuster (Member)
Guru^2
Messaggi: 1620
Iscritto: 27/09/2013
|
da terminale: "mingw32-g++.exe -v "e scopri subito la versione del compilatore.
|
|
AldoBaldo (Member)
Guru
Messaggi: 699
Iscritto: 08/01/2015
|
A che terminale ti riferisci? Alla console del DOS? Non ricordo come si fa a lanciarla, e comunque non ho trovato il file mingw32-g++.exe da nessuna parte sull'hard disk, quindi non saprei quale può essere il percorso... boh?
Edit: il file exe l'ho poi trovato - mingw32-gcc-4.7.1.exe
Ultima modifica effettuata da AldoBaldo il 29/09/2015 alle 17:35
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti. |
|
TheDarkJuster (Member)
Guru^2
Messaggi: 1620
Iscritto: 27/09/2013
|
chiamasi prompt dei comandi, si accede con tasto windos + R, scrivi cmd.exe e dai invio.
Fai "cd cartella/dell/eseguibile/" e poi "mingw32-gcc-4.7.1.exe -v" ti dice la versione.
|
|