Question

Certes, je suis un novice sans scrupule, mais cela m’a laissé perplexe. Je travaille sur une implémentation de liste chaînée pour la pratique et j'obtiens une erreur de segmentation en ajoutant simplement une variable à la fonction split_node:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct Node {
    struct Node *child;
    char *content;
};

void print_list(struct Node node);
void split_node(struct Node *node, int position);

int main() {

    struct Node head, second, third;

    head.content = "first";
    second.content = "second";
    third.content = "i'm third";

    head.child = &second;
    second.child = &third;

    print_list(head);
    split_node(&head, 3);
    print_list(head);

    return 0;
}

void print_list(struct Node node) {
    printf("%s\n", node.content);
    if(node.child) print_list(*node.child);
}

    /*
    Split node into two nodes, with the first position characters of the node's content remaining with node, and the remainder being copied to the new node. (It doesn't yet truncate the first node's string, but does do the copy.)
    */
void split_node(struct Node *node, int position) {
    if(position >= strlen((*node).content)) return;
    struct Node newNode;
    newNode.child = (*node).child;
    (*node).child = &newNode;

    int length = (strlen((*node).content) - position);
    newNode.content = malloc(sizeof(char) * (length + 1));
    strncpy(newNode.content, (*node).content + sizeof(char) * position, length);
    newNode.content[length] = '\0';

    //int foo;
}

Ce code est compilé (gcc -Wall -o list list.c) et fonctionne correctement:

$ ./list
first
second
i'm third
first
st
second
i'm third

Mais si je ne commente pas int foo à la fin de noeud_solidé , je compile et exécute, je reçois:

$ ./list
first
second
i'm third
first
st
Segmentation fault

gdb me donne cette trace:

#0  0x91d6ae70 in strlen ()
#1  0x91dd3126 in puts ()
#2  0x00001f21 in print_list (node={child = 0xbcec815b, content = 0x8b000000 <Address 0x8b000000 out of bounds>}) at list.c:41
#3  0x00001f3c in print_list (node={child = 0x8fe0154b, content = 0x1ff6 "i'm third"}) at list.c:42
#4  0x00001f3c in print_list (node={child = 0xbffff568, content = 0x1fef "second"}) at list.c:42
#5  0x00001f3c in print_list (node={child = 0xbffff570, content = 0x1fe9 "first"}) at list.c:42
#6  0x00001ee0 in main () at list.c:33

Pourquoi l'ajout d'une définition de variable provoquerait-il une erreur de segmentation? Il semble briser le pointeur de contenu du noeud nouvellement créé. Je suis confus; toute aide?

Était-ce utile?

La solution

Vous devez allouer dynamiquement vos nœuds (à l'aide de malloc).

Comme vous l'avez, votre nouveau noeud est déclaré sur la pile. Lorsque la fonction fractionnée revient, ce nouveau noeud n'est plus une mémoire valide.

L'ajout d'une variable provoque une erreur de segmentation car cette variable modifie la disposition de la pile, ce qui entraîne un comportement légèrement différent lorsque la fonction est renvoyée.

Autres conseils

Essayez de définir la propriété enfant Nodes sur NULL, C ne met pas automatiquement la mémoire à zéro de façon à donner l’impression que votre fichier contient des déchets (ou que vous pourriez utiliser calloc au lieu de malloc). La réponse de SoapBox est également correcte.

Valgrind est un excellent outil pour vous aider à trouver ces types de problèmes. Vous pouvez simplement faire "valgrind myappname". à partir de la ligne de commande et il vous donnera des détails sur ces types d’erreurs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top