2016-07-16 1 views
1

Im essayant de compiler et d'exécuter ce petit code C++ en utilisant g ++ 5.1, il est compilé correctement, quand je l'exécute sur linux j'obtiens ce message d'erreur: "Segmentation fault (core dumped)".C++: erreur de segmentation sous Linux OS

Mais le même correctement code exécuté sur Mac OS X, mais pas sur 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; 
} 

i essayé simple assigne (node-> data = "string"), mais je suis le même problème Toute aide s'il vous plaît!

+5

Pourquoi utilisez-vous 'malloc' dans du code C++? 'new' va initialiser l'objet chaîne -' malloc' ne l'est pas. –

+1

Qui continue d'enseigner des trucs comme ça? N'arrive-t-il pas à ces gens que les années 80 sont terminées? :/ –

+1

Pour développer ce que @EdHeal a dit: il ne suffit pas d'allouer juste sizeof (struct node) octets, puis de commencer à les utiliser. Vous devez vous assurer que le constructeur de l'objet chaîne s'exécute également, de sorte que l'état privé de l'objet nœud sera initialisé correctement. Pour ce faire, vous devez utiliser le nouvel opérateur (par exemple, noeud = noeud de la structure * noeud = nouveau noeud;) –

Répondre

5

Vous ne pouvez pas malloc une chaîne C++. Vous devriez utiliser correctement new et delete, au moins, pour que les constructeurs soient invoqués. Arrêtez d'utiliser C en C++.

Idéalement, vous n'utiliserez même pas new; Il suffit d'avoir un objet normal avec une durée de stockage automatique ou, si vous avez désespérément besoin d'une allocation dynamique, std::make_unique.

La gestion manuelle de la mémoire n'est pas nécessaire en 2016.

+1

'Il n'y a pas besoin de gestion manuelle de la mémoire en 2016.' Je suppose que je peux jeter mes allocateurs personnalisés alors .. :( –

+0

@Lightness Races in Orbit: vous voulez dire un pointeur intelligent prenant la mémoire manuelle gestion – solti

+1

Oui, c'est ce que 'make_unique' renvoie après tout –

5

Avec C++, oubliez malloc(). Si vous souhaitez allouer un objet new utiliser:

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

Le problème avec malloc() est qu'il alloue seulement la mémoire non initialisée. Il n'assure pas la sémantique C++ de la création d'objet. Ainsi, la chaîne à l'intérieur de votre noeud n'est pas initialisée à un état valide. Cela provoque l'affectation de cette chaîne à UB.

Si vous avez vraiment besoin d'utiliser malloc() en C++, vous aurez besoin d'utiliser un placement new après pour initialiser l'objet à un état valide (online demo).

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

Pourquoi la chaîne doit être initialisée puisqu'il remplace quoi que ce soit avec "chaîne" ... comment le nouveau s'assure-t-il que le constructeur de chaîne est appelé? – solti

+3

@solti C'est ce que fait 'new', il alloue de la mémoire et appelle le constructeur. –

+1

@GillBates puisque la chaîne n'est pas construite (parce que le constructeur n'est pas appelé pour la chaîne), c'est pourquoi le segfault? – solti