2015-08-06 14 views
5

Codice:Perché l'assegnazione valarray non ridimensiona l'assegnatario per la documentazione?

#include <valarray> 
#include <iostream>  

using namespace std; 

int main() 
{ 
    valarray<int> v0(2, 4); 
    valarray<int> v1; 
    v1 = v0; 
    cout << "v0.size: " << v0.size() << endl; 
    cout << "v1.size: " << v1.size() << endl; 
    cout << "v0[0]: " << v0[0] << endl; 
    cout << "v1[0]: " << v1[0] << endl; 
} 

uscita:

v0.size: 4 
v1.size: 0 
v0[0]: 2 
Segmentation fault 

Per l'assegnazione:

v1 = v0; 

penserei il costruttore:

valarray<T>& operator=(const valarray<T>& other); 

dovrebbe essere utilizzato un Secondo lo documentation, credo che v1 debba essere ridimensionato e il contenuto di v0 copiato in esso, elemento per elemento. Quindi cosa sta succedendo davvero?

$ g++ --version 
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11) 
+4

Quale piattaforma, compilatore, versione, implementazione della libreria standard ecc. State usando? Funziona bene [qui] (http://coliru.stacked-crooked.com/a/dc1620e9787f0d13). – Praetorian

+1

Sei sicuro che questo è il tuo output? Il testo non corrisponde nemmeno alle stringhe che hai passato a 'cout'. –

+1

@Bryant L'output mostrato non corrisponde al codice. –

risposta

6

Poiché si utilizza il vecchio C++.

A partire da C++ 11, la destinazione viene ridimensionata per corrispondere alla sorgente.
Ecco perché alcuni contributori qui non sono riusciti a riprodurre il problema (inoltre, UB ha risultati imprevedibili). È anche il motivo per cui the cppreference.com article states that a resize is first performed (anche se una dichiarazione di non responsabilità è valida solo perché C++ 11 potrebbe essere stato bello). [Questo è stato risolto.]

[C++11: 23.6.2.3]assegnazione valarray [valarray.assign]

valarray<T>& operator=(const valarray<T>& v);

    è assegnato Ciascun elemento della matrice *this la valore dell'elemento corrispondente dell'array di argomenti. Se la lunghezza di v non è uguale alla lunghezza di *this, ridimensiona *this per rendere i due array della stessa lunghezza, come se chiamando resize(v.size()), prima di eseguire l'assegnazione.

    Post-condizione: size() == v.size().

Tuttavia, in C++ 03, il codice ha un comportamento non definito.
Ecco perché stai riscontrando un errore di segmentazione con la tua vecchia toolchain. È anche il motivo per cui, quando il problema è stato sollevato come nel 2003, è stato respinto come non valido perché l'implementazione era effettivamente conforme in quel momento.

[C++03: 23.3.2.2]assegnazione valarray [valarray.assign]

valarray<T>& operator=(const valarray<T>& v);

    Ciascun elemento della matrice *this viene assegnato il valore del corrispondente elemento della matrice di argomento.Il comportamento risultante non è definito se la lunghezza dell'array di argomenti non è uguale alla lunghezza dell'array *this.

+0

Vorrei poter eseguire il ping [@Cubbi] (https://stackoverflow.com/users/273767/cubbi); [ha aggiunto quel testo] (http://en.cppreference.com/mwiki/index.php?title=cpp/numeric/valarray/operator%3D&diff=prev&oldid=68852). [Non so] (http://en.cppreference.com/w/Talk:cpp/numeric/valarray/operator%3D) il modo migliore per formattare un chiarimento nell'articolo. –

+0

L'ho modificato. Pensa che sia il formato corretto, perché corrisponde a quello della descrizione del costruttore dell'intervallo [qui] (http://en.cppreference.com/w/cpp/container/vector/vector). (quindi dovresti modificare la tua risposta ora) – Praetorian

+0

Modificato lo stile, ora sembra la differenza di revisione inline mostrata [qui] (http://en.cppreference.com/w/cpp/language/default_constructor#Deleted_implicitly-declared_default_constructor) – Praetorian