4
votes

Pourquoi une erreur de segmentation (core dumped) quand je cin une chaîne dans node-> name?

Erreur de segmentation (core dumped) lorsque je getline (cin, node-> name) .

J'ai corrigé en déclarant une chaîne str dans ma fonction d'entrée puis node-> name = str . Mais a couru jusqu'à la ligne cin >> node-> year et a toujours atteint l'erreur de segmentation.

struct client
{
    int code;
    string name;
    int year;
    float maths, physics, chemistry;
    struct client *next;
};

struct client* input()
{
    struct client *node = (struct client *)malloc(sizeof(struct client));

    cout << "Code: ";
    cin >> node->code;

    cout << "Name: ";
    cin.ignore();
    getline(cin, node->name);

    cout << "Year: ";
    cin >> node->year;

    cout << "Maths, Physics, Chemistry: ";
    cin >> node->maths >> node->physics >> node->chemistry;

    node->next = NULL;

    return node;
}


5 commentaires

Ce n'est pas c .


En jetant de la mémoire malloc ed, vous évitez d'appeler le constructeur sur votre nœud . Il n'est donc pas légal d'en faire quoi que ce soit.


J'ai une question concernant getline : prend-il une chaîne initialisée ou s'occupe-t-il de l'initialiser lui-même? Parce que cela peut être la source du bug (vraie question)


@BoBTFish Pas tout à fait: il est légal d'appeler son constructeur, via placement-new.


@ joH1 S'il n'est pas initialisé, ce n'est pas une chaîne.


3 Réponses :


5
votes

Puisque vous utilisez malloc pour allouer votre mémoire, rien dans le nouveau nœud ne sera initialisé. En particulier, nom de chaîne ne sera pas initialisé correctement et cela posera des problèmes lorsque vous essayez de l'utiliser, car toute fonctionnalité l'impliquant repose sur le fait que la chaîne a été correctement construite. Au lieu de ceci:

client *node = new client;

Faites ceci:

struct client *node = (struct client *)malloc(sizeof(struct client));

De cette façon, le nœud (et le nom ) dans sont correctement initialisés.


0 commentaires

2
votes

Comme les commentaires le suggèrent, votre chaîne fait probablement référence à std :: string , qui est une classe non POD. Cela signifie que vous devez appeler le constructeur etc. pour utiliser l'objet, pas seulement allouer la mémoire.

Cela signifie que vous devez faire à la place:

std::unique_ptr<client> = std::make_unique<client>();

Et de même , pour le détruire:

delete node;

Ou, mieux, utilisez un type de pointeur RAII comme std :: unique_ptr en C ++ 11:

client *node = new node;


0 commentaires

1
votes

Nous avons deux alternatives en plus de celles déjà mentionnées dans d'autres réponses.


La méthode recommandée est de refactoriser votre code et d'éviter l'allocation dynamique. Utilisez des variables automatiques et déplacez la sémantique à la place.

node->~client();
free(node);

(Vous pouvez utiliser client directement à la place de struct client )

Il s'agit de la méthode préférée pour afficher les questions marquées 'c ++' "rel =" tag " c ++ .


Si vous insistez sur malloc , alors appelez explicitement le constructeur via placement-new:

client* node = (client*) malloc(sizeof(client));
new (node) client{};


0 commentaires