Ошибка ошибки сегментации в C при попытке печати в файл - PullRequest
0 голосов
/ 22 ноября 2018

Я создал функцию, которая должна получать двоичное дерево в аргументе, имя файла во входных данных пользователя и внутри этого файла печатать двоичное дерево для последующего преобразования в изображение через graphviz.

Тип бинарного дерева:

struct noeud_s;

typedef struct noeud_s noeud;

typedef noeud* arbre;

struct noeud_s{
  char* valeur;
  arbre gauche;
  arbre droit;
};

2 функции, которые я создал:

void create_dot(arbre racine)
{
  FILE *f;
  char file_name[100];
  printf ("Nom du fichier a creer (Ajouter .dot a la fin): ");
  scanf ("%s", file_name);
  printf("Name: %s\n", file_name);
  printf ("Creation du fichier dot\n");
  f = fopen(file_name, "w");
  if (f == NULL)
  {
    printf("NULL\n");
  }
  fprintf(f, "digigraph tree {\n");
  write_to_dot(f, racine);
  fprintf(f, "}");
  fclose(f);
}

void write_to_dot(FILE *f, arbre racine)
{
  if (racine == NULL)
  {
    return;
  }
  if (racine != NULL)
  {
    fprintf(f, "%s -> %s [label = \"non\"]\n", racine -> valeur, racine -> gauche -> valeur);
    fprintf(f, "%s -> %s [label = \"oui\"]\n", racine -> valeur, racine -> droit -> valeur);
    write_to_dot(f, racine -> gauche);
    write_to_dot(f, racine -> droit);
  }
  return;
}

Что касается отладки, я вычитал, что моя ошибка сегментации происходит внутри функции write_to_dot,Но поскольку я не могу правильно обработать GDB, я хотел бы, чтобы вы помогли мне найти мою ошибку сегментации и объяснить ее, пожалуйста.

1 Ответ

0 голосов
/ 22 ноября 2018

Код распечатывает двоичное дерево.Нет кода, показывающего, как строятся узлы, но в типичных бинарных деревьях конечные узлы имеют NULL левый и правый дочерние узлы (или gauche и droit как бы).

Функция write_to_dot завершится с ошибкой на первом листовом узле (если не на пустой стороне промежуточного узла ветвления), потому что racine->gauche и racine->droit будут NULL, но они по-прежнему разыменовываются -racine->gauche->valeur без проверки.

Хотя у меня нет всего кода, хотя бы тестирование этого условия решит одну из проблем:

void write_to_dot ( FILE *f, arbre racine )
{
    if ( racine != NULL )
    {
        if (racine->gauche != NULL)
            fprintf ( f, "%s -> %s [label = \"non\"]\n", racine->valeur, racine->gauche->valeur );
        else
            fprintf ( f, "%s -> NULL [label = \"non\"]\n", racine->valeur );

        if (racine->droit != NULL)
            fprintf ( f, "%s -> %s [label = \"oui\"]\n", racine->valeur, racine->droit->valeur );
        else
            fprintf ( f, "%s -> NULL [label = \"oui\"]\n", racine->valeur );

        write_to_dot ( f, racine->gauche );
        write_to_dot ( f, racine->droit );
    }
}
...