2016-07-16 6 views
1

Im triying zu kompilieren und Ausführen dieser kleinen C++ - Code mit g ++ 5.1, ist es in Ordnung, wenn ich es auf linux ausführen, bekomme ich diese Fehlermeldung: "Segmentation fault (core dumped)".C++: Segmentierung Fehler (Core Dumped) Auf Linux OS

Aber die gleiche Code läuft korrekt auf osx aber nicht auf Linux:

#include <iostream> 
#include <string.h> 
#include <stdlib.h> 
#include <string.h> 
using namespace std; 

struct node { 
std::string data; 
}; 

int main() { 
    struct node * node = (struct node *) 
    malloc(sizeof(struct node)); 

    node->data.assign("string"); 
    // node->data = "string" --> same issue 

    return 0; 
} 

Ich habe versucht, eine einfache assigne (node-> data = "string"), aber ich habe das gleiche Problem Jede Hilfe bitte!

+5

Warum verwenden Sie 'malloc' in C++ - Code? 'new' initialisiert das String-Objekt -' malloc' nicht. –

+1

Wer unterrichtet solche Sachen? Kommt es diesen Leuten nicht in den Sinn, dass die 80er Jahre vorbei sind? :/ –

+1

Um zu erweitern, was @EdHeal sagte: Es ist nicht genug, nur sizeof (struct node) Bytes zuzuweisen und dann anfangen, sie zu verwenden. Sie müssen sicherstellen, dass der Konstruktor des Zeichenfolgenobjekts ebenfalls ausgeführt wird, damit der private Status des Knotenobjekts ordnungsgemäß initialisiert wird. Dazu müssen Sie den neuen Operator verwenden (z. B. node = struct node * node = new node;) –

Antwort

5

Sie können nicht malloc eine C++ - Zeichenfolge. Sie sollten zumindest new und delete richtig verwenden, damit Konstruktoren aufgerufen werden. Beenden Sie die Verwendung von C in C++.

Idealerweise würden Sie nicht einmal new; haben Sie einfach ein normales Objekt mit automatischer Speicherdauer oder, wenn Sie dringend eine dynamische Zuweisung benötigen, std::make_unique.

Im Jahr 2016 ist keine manuelle Speicherverwaltung erforderlich.

+1

'Es gibt keine Notwendigkeit für die manuelle Speicherverwaltung im Jahr 2016. Ich denke, ich kann meine benutzerdefinierten Allokatoren dann wegwerfen .. :( –

+0

@Lightness Races in Orbit: Sie meinen, intelligente Zeiger über manuelle Speicher Management? – solti

+1

Ja, das ist, was 'make_unique' schließlich zurückgibt. –

5

Mit C++ vergessen Sie malloc(). Wenn Sie ein Objekt zuordnen wollen new verwenden:

node * n = new node; // or if your variable should be called node 
         // you'd need new struct node to disambiguate 

Das Problem mit malloc() ist, dass es ordnet nur auf nicht initialisierten Speicher. Es stellt nicht die C++ - Semantik der Objekterstellung sicher. Daher wird die Zeichenfolge in Ihrem Knoten nicht in einen gültigen Zustand versetzt. Dies bewirkt, dass die Zuweisung dieser Zeichenfolge UB ist.

Wenn Sie wirklich malloc() in C++ verwenden müssen, würden Sie brauchen ein placement new danach verwenden, um das Objekt in einen gültigen Zustand zu initialisieren (online demo).

void *p = malloc(sizeof(node)); // not so a good idea ! 
node *n2 = new (p)node;   // but ok, it's feasible. 
+0

Warum muss der String initialisiert werden, da er was auch immer dort durch "String" ersetzt ... auch wie stellt das neue sicher, dass der Konstruktor von String aufgerufen wird? – solti

+3

@solti Das ist was "neu" tut, es reserviert Speicher und ruft den Konstruktor auf. –

+1

@GillBates da String nicht konstruiert ist (weil Konstruktor nicht für String aufgerufen wird), deshalb ist der segfault? – solti

Verwandte Themen