2016-02-25 18 views
12

Possiedo un costruttore che assegna diversi blocchi di memoria utilizzando l'operatore new.Eccezione allocazione memoria in Constructor

X::X() { 
    a = new int[100]; 
    b = new char[100]; 
    c = new float[100]; 
} 

La mia domanda è, se l'assegnazione di c non riesce e il costruttore genera un'eccezione, sarà la memoria per a e b essere liberato automaticamente?

+9

No. Questo è ciò che è utile per la tecnica nota come [RAII] (https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization). Se vuoi una classe per la gestione di un array dinamico, è chiamata ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector). Non provare a scriverne uno da solo. – BoBTFish

+2

Lettura richiesta: [Perché i programmatori C++ dovrebbero ridurre al minimo l'uso di "nuovo"?] (Http://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new) –

+2

Oltre all'utilizzo di 'std :: vector', se la dimensione è una costante fissa in fase di compilazione e la memoria non deve essere allocata dall'heap, si consideri l'uso di [' std :: array'] (http: // it .cppreference.com/w/cpp/container/array). –

risposta

13

La memoria a cui a e b punto sarebbe non essere liberato automaticamente. Ogni new[] deve essere bilanciato in modo esplicito con delete[].

Anche se il distruttore ha eseguito la cancellazione (supponendo che a, e c siano membri della classe), si perderebbe ancora memoria. Questo perché il distruttore non dovrebbe chiamare in questo caso poiché l'oggetto non è riuscito a costruire.

L'utilizzo di std::vector s ovvierebbe a questi problemi.

+4

tecnicamente, 'a' e' b' vengono automaticamente distrutti. Ma distruggere un puntatore non fa nulla. –

3

No, non lo faranno. Ecco perché è necessario conoscere RAII e in particolare contenitori e puntatori intelligenti.

Nel tuo caso, è possibile utilizzare std::vector<T> invece di new T[100], ad esempio.

9

a, b e c verranno tutti distrutti. A seconda dei tipi, potrebbero o meno liberare memoria. Se sono puntatori, i loro distruttori non fanno nulla e la memoria perde. Se sono una sorta di puntatore intelligente, presumibilmente i loro distruttori rilasceranno la memoria.

+0

Non verranno distrutti tutti e tre i membri dei dati? I loro costruttori hanno tutti finito di funzionare quando il costruttore X inizia a funzionare. – templatetypedef

+0

(Si noti che i distruttori per i membri dati, se sono indicatori non elaborati, non indirizzano i puntatori.) – templatetypedef

+3

Tecnicamente corretto: il miglior tipo di corretto. –

1

La variabile a e b sarà non essere automaticamente distrutti di sicuro. Nel tuo caso devi usare questo std :: vector. Questo perché ogni volta che utilizziamo un nuovo operatore [] per questo dobbiamo definire esplicitamente una cancellazione [].