2016-04-09 7 views
2

Diese Version von Code funktioniert gut:Ändern Datentyp für ein Klassenattribut eine segfault bei der Erstellung eines Unterklasse-Objekt verursacht

class Object 
{ 
public: 

    // Object(string name, string state) <-- string version 
    Object(string name, bool state) 
    { 
     this->name = name ; 
     this->state = state ; 
    } 

protected: 
    string name ; 
    bool state ; 
    // string state ; <-- string version 
}; 



class Tool : public Object 
{ 
public: 
    Tool(string name):Object(name,state) 
    { 
     this->state = true ; 

     //this->state = "true" ; <-- string version 
    } 
}; 


int main() 
{ 

    Tool* tool = new Tool("name") ; 


    cin.get() ; 
    return 0 ; 
} 

... aber wenn ich die state machen Attribut eine string (und Ersatz Codezeilen mit den nahegelegenen "String-Versionen", die ich auskommentierte, dann gibt das Programm nach einer fehlerfreien Kompilierung zur Laufzeit einen segfault.

Beim Erstellen von Basisklassenobjekten treten keine Probleme auf.

Die Debugger-Ausgänge:

#0 0x45b74c std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)() (??:??) 
#1 ?? ??() (??:??) 

Warum machen die state ein string Probleme verursachen?

Antwort

2
Tool(string name):Object(name,state) 

Sie versuchen, ein nicht initialisierte Mitglied state (das protected Mitglied der Basisklasse Object) als Argument für die Object verwenden Konstruktor ‚s Konstruktor, sollte es durch Object initialisiert werden.‘ Wenn eine nicht initialisierte Variable zu UB führt, bedeutet das, dass alles passieren kann. In Ihrem Fall verursacht es einen Segmentfehler, wenn Sie std::string verwenden.

BTW: Sie sollten eine Kompilierungswarnung dafür bekommen. Wie clang with -Wall.

source_file.cpp:28:35: warning: base class 'Object' is uninitialized when used here to access 'Object::state' [-Wuninitialized] 
    Tool(string name):Object(name,state) 
           ^
+0

Wie macht das 'state' ein' bool' das Problem, nicht zu erscheinen? Seine invariante Größe oder ...? – dziadek1990

+1

@ dziadek1990 'bool' ist ein eingebauter Typ, während' std :: string' ein Klassentyp ist, einen nicht-trivalen Konstruktor und eine komplexe innere Konstruktion hat. 'bool' könnte in diesem Fall sicherer sein, aber UB ist UB, nichts ist garantiert. – songyuanyao