2013-04-03 8 views
6
class foo { 
    public: 
    friend ostream& operator << (ostream &os, const foo &f); 
    foo(int n) : a(n) {} 
    private: 
    vector <int> a; 
}; 

ostream& operator << (ostream &os, const foo &f) { 
    for (int i = 0; i < f.a.size(); ++i) 
     os << f.a[i] << " "; 
    os << endl; // why is this line a must? 
} 

int main(void) { 
    foo f(2); 
    cout << f << endl; 
    return 0; 
} 

In dem obigen Code, wenn die markierte Zeile entfernt wird, wird es einen Segment Fehler Fehler, kann jemand erklären, warum?Überlasteter ostream operator segmentation fault wenn kein endl

+1

Warum niemand den Code in Frage zu überprüfen cares? Der Compiler sollte Sie vor einem solchen Fehler gewarnt haben - "... Warnung: Keine Rückgabeanweisung in der Funktion, die nicht void [-Wreturn-type] zurückgibt" Siehe http://liveworkspace.org/code/2ygK20$1 } ^ – SChepurin

Antwort

16
ostream& operator << (ostream &os, const foo &f) { 
    for (int i = 0; i < f.a.size(); ++i) 
     os << f.a[i] << " "; 
    os << endl; // why is this line a must? 
} 

ist nicht zwingend. Die segfault verursacht wird, weil Sie nicht os zurückkehr

ostream& operator << (ostream &os, const foo &f) { 
    for (int i = 0; i < f.a.size(); ++i) 
     os << f.a[i] << " "; 
    return os; // Here 
} 

es ist nicht definiertes Verhalten, wenn Sie nicht die Ostream zurück. Die endl spült Ihre os hier. Deshalb scheint es, als ob es funktioniert.

EDIT: Bo nach Persson

Das o < < Endl Warum es in diesem Fall arbeitet; ist ein weiterer Operator-Aufruf, der tatsächlich os durch zurückgibt, wo es "platziert wird, wo ein Rückgabewert erwartet wird" (wahrscheinlich ein Register). Wenn der Code eine weitere Ebene zur Hauptzurückkehrt, ist der Verweis auf os noch da

+0

Ist das implizite 'int' (?), das zurückgegeben würde, wenn nichts angegeben oder sein Wert irgendwie standardisiert wäre? –

+4

Hier wird kein implizites 'int' zurückgegeben. Es wird ganz klar als "ostream &" zurückgegeben. Ohne eine 'return'-Anweisung erhalten Sie also, was auch immer Dschunken nach der Funktion am richtigen Ort auf dem Stapel sind. Es passiert einfach, dass mit dem 'os << endl 'dieser Junk etwas ist, das keinen Absturz verursacht. – BoBTFish

+2

@honk In C++ gibt es kein implizites 'int'. Wenn etwas von einer nicht-leeren Funktion nicht zurückgegeben wird, ist dies ein undefiniertes Verhalten, Punkt. – Angew