6

Kompilator rzuca wykonania segfault na następujący kod:struct zawierający ciąg znaków powoduje błąd segmentacji na jego zlecenie po jego utworzeniu za pomocą alokacji pamięci dynamicznej

#include <iostream> 
#include <string> 
using namespace std; 

struct Node{ 
    int data; 
    void *next; 
    string nodeType; 
}; 

Node* initNode(int data){ 
    Node *n = (Node*)malloc(sizeof(Node)); 
    n->data = data; 
    n->next = NULL; 
    n->nodeType = "Node"; //if this line is commented it works else segfault 
    return n; 
} 

int main() { 
    Node *n1 = initNode(10); 
    cout << n1->data << endl; 
} 

Czy ktoś mógłby wyjaśnić, dlaczego przypisanie ciąg nie działa wewnątrz struktury, które jest przydzielany dynamicznie, gdzie w przypadku alokacji statycznej, dlaczego działa?

gdzie w następujący sposób to działa:

Node initNode(string data){ 
    Node n; 
    n.data = data; //This works for node creation statically 
    n.next = NULL; 
    n.nodeType = "Node"; //and even this works for node creation statically 
    return n; 
} 

a następnie w głównym funkcji:

int main() { 
    Node n2 = initNode("Hello"); 
    cout << n2.data << endl; 
} 
+1

'malloc' po prostu przydziela pamięć, nie * konstruuje * instancji obiektu, co oznacza, że ​​konstruktor' string' nie jest wywoływany. –

+2

Ogólna zasada: nie używaj C 'malloc' w C++, używaj' new', a właściwie nie używaj 'new' jeśli to możliwe, i używaj' make_shared' lub 'std :: unique_ptr' (C + +11) –

Odpowiedz

8

to nie działa, ponieważ nie faktycznie skonstruowania instancji Node Into the pamięć, którą wy malloc.

Należy użyć new zamiast:

Node *n = new Node{}; 

malloc przydziela tylko pamięć, że nie ma pojęcia, co klasa lub jak instancję jednego. Powinieneś generalnie nie używać go w C++.

new przydziela pamięć i tworzy instancję klasy.

+0

Hej, to działa: Węzeł * n = nowy węzeł(); Ale myślałem, że malloc rzeczywiście przydzieli pamięć, tworząc instancję? Czy to nie prawda? Czy możesz wyjaśnić lub podać wskazówki dotyczące różnicy między robieniem "nowego" a "malloc" i kiedy go użyć? – Dhwanit

+0

Poprawiłem moją odpowiedź, podając więcej szczegółów. – TartanLlama

+0

racja! dzięki! cóż, faktycznie miałem wrażenie, że konstruktor ciągu zostanie wywołany, gdy zrobię malloc, ponieważ jest to ciąg znaków, a nie ciąg * – Dhwanit

4

Nie ma miejsca, w którym wykonywany jest konstruktor std :: string.

Należy użyć nowego

example *e = new example; 

lub umieszczenie nowy

void *example_raw = malloc(sizeof(example)); 
example *e = new(example_raw) example; 
+0

dziękuję, że działa to w ten sposób! :) – Dhwanit

1

string w C++ jest klasa i tworzyć obiekty String używać new zamiast malloc jak poniżej.

Node *n = new Node{}; 
3
Node *n = (Node*)malloc(sizeof(Node)); 

ta obsada jest nonsens. Nie można po prostu powiedzieć kompilatorowi, aby udawał, że fragment danych, który właśnie przydzielisz, zawiera poprawny obiekt Node, a następnie nim manipuluje.

+0

yup w prawo!cóż, faktycznie miałem wrażenie, że konstruktor ciągu zostanie wywołany, gdy zrobię malloc, ponieważ był ciąg, a nie ciąg * wewnątrz węzła – Dhwanit