2013-03-05 5 views
6

Il seguente codice è sicuro, a condizione che non legga alcun elemento dell'array della struct senza prima averlo impostato con un valore reale? Grazie.È corretto copiare i dati non inizializzati se sarà inutilizzato/impostato in seguito?

const int data_size = 5; 

struct Testing 
{ 
    int data[data_size]; 

    Testing(const int data[data_size]) 
    { 
     std::copy(data, data + data_size, this->data); 
    } 
}; 

int main() 
{ 
    int data[data_size]; 
    data[2] = 57; 

    Testing t(data); 

    t.data[1] = 93; 
} 
+2

Non so perché vorresti farlo, ma dovrebbe essere sicuro. Immondizia nella spazzatura, ma la spazzatura non dovrebbe cadere dal bidone della spazzatura e puzzare la memoria circostante. –

+2

Con tipi non banalmente assegnabili è molto probabilmente pericoloso, e sicuramente un comportamento indefinito. Con tipi banalmente assegnabili, è * probabilmente * sicuro, nella maggior parte delle condizioni, ma sicuramente è ancora un comportamento indefinito. –

+0

Ciao Ben, non capisco il tuo commento. Cosa intendi banalmente assegnabile? –

risposta

9

std::copy è definita come facendo *(result + n) = *(first + n) per ciascun elemento della sequenza (§25.3.1). Il valore dato da *(first + n) è un'espressione lvalue (§5.3.1/1), nel tuo caso riferita a un valore non inizializzato. Poiché l'operatore di assegnazione si aspetta un valore come operando corretto (questo è ill-specified), ciò comporterà la conversione da lvalue a valore. Ivalue a rvalue conversione un'espressione riferimento a un valore non inizializzato è un comportamento indefinito (§4.1):

Se l'oggetto a cui il glvalue riferisce non è un oggetto di tipo T e non è un oggetto di un tipo derivato da T, o se l'oggetto non è inizializzato, un programma che richiede questa conversione ha un comportamento non definito.

Quindi il tuo codice ha un comportamento non definito. La soluzione è ovviamente per inizializzare gli elementi dell'array (forse con int data[data_size] = {};).

+0

quindi quickfix potrebbe essere aggiungere memset (dati, 0, sizeof (dati)); subito dopo la dichiarazione dell'array in main(). – Slava

+3

@ Slava: O semplicemente inizializza correttamente. 'dati int [data_size] = {};' –

+0

@BenjaminLindley buon punto, questo è molto più breve. – Slava

Problemi correlati