2016-03-21 11 views
0

Dies ist das Programm, das ich in Reaktion auf eine Übung in C++ Primer schrieb. Ich weiß nicht, warum es die letzte Zahl im Vektor zweimal druckt.Über dynamischen Speicher in C++

vector<int>* create_dyn_vec() { 
    return new vector<int>(); 
} 
void give_value(vector<int>* ivec_ptr, istream& in) { 
    int i; 
    while (in) { 

     in >> i; 
     ivec_ptr->push_back(i); 
    } 
} 
void print(vector<int>* ivec_ptr) { 
    for (auto& i : *ivec_ptr) 
     cout << i << " " << endl; 
} 

int main() { 
    auto ivec_dyn_ptr=create_dyn_vec(); 
    give_value(ivec_dyn_ptr, cin); 
    print(ivec_dyn_ptr); 
    delete ivec_dyn_ptr; 
} 

Antwort

4

Für Ihre unmittelbare Problem der duplizierten letzte Zahl, ersetzen

while (in) { 
    in >> i; 

mit nur

while(in >> i) { 

Der ursprüngliche Code überprüft nicht, ob der Eingabevorgang erfolgreich ist, bevor es die anfügt Nummer zum Vektor. Somit ist am Ende der Datei, wo die Eingabeoperation fehlschlägt, die Nummer unverändert und wird angehängt.

Im Ersetzungscode versucht der Ausdruck in >> i die Eingabeoperation und erzeugt einen Verweis auf den Datenstrom als Ausdruck Ergebnis. Die Referenz wird als whileBedingung verwendet und bei Verwendung als Bedingung wird sie in bool konvertiert. Diese Konvertierung wird vom Stream so definiert, dass not in.fail() erzeugt wird, wobei fail die Memberfunktion ist, die angibt, ob die letzte E/A-Operation in diesem Stream fehlgeschlagen oder erfolgreich war.


Tipp: Statt Zeiger um Sie vorbei C++ Referenzen verwenden können.


Mit mehr idiomatischen C++ wäre dieser Code wie & hellip;

void load_from(istream& in, vector<int>& v) 
{ 
    int i; 
    while(in >> i) 
    { 
     v.push_back(i); 
    } 
} 

void print(vector<int> const& v) 
{ 
    for(auto const& i : v) 
    { 
     cout << i << endl; 
    } 
} 

int main() 
{ 
    vector<int> v; 
    load_from(cin, v); 
    print(v); 
} 

Hinweis, dass es keine new oder delete Ausdrücke hier. Ein großer Teil der Verwendung von Auflistungsklassen wie vector ist, dass es Speicherverwaltung automatisiert. Das Hinzufügen von manueller Speicherverwaltung an der Spitze vereitelt eher den Zweck.

Haftungsausschluss: Ich habe nicht versucht, den Code zu kompilieren.

+0

Vielen Dank für Ihren Rat. Aber ich habe es einfach so gemacht, wie es die Frage erfordert. Es ist eine Übung, dynamische Speicher zu verwalten. – yughred

3

Da das Ende der Datei Zustand auf einem std::istream gesetzt nach Sie von ihm zu lesen versuchen, nicht vor:

while (in) { 

    in >> i; 
    ivec_ptr->push_back(i); 
} 

Nachdem Sie den letzten Wert in der Datei gelesen haben, Sie starten die while-Schleife wieder:

while (in) { 

Dies zu true auswertet, weil das Ende der Datei Zustand noch nicht erreicht ist.

in >> i; 
    ivec_ptr->push_back(i); 

Sie versuchen dann, den nächsten Wert zu lesen. Dieser Versuch schlägt fehl und setzt das Ende der Dateibedingung auf std::istream. Aber du push_back() der Wert für den Vektor trotzdem. Dies ist der letzte Wert, den Sie in der Datei gelesen haben, und hängt ihn effektiv ein zweites Mal an den Vektor an.

Bei der nächsten Iteration beendet das Ende der Dateibedingung die while-Schleife.

+0

Vielleicht lohnt es sich zu erklären, wie es zu beheben (d. H. Während (in >> in)) und warum das funktioniert. – Borgleader