Przekazywanie wskaźnika fo funkcji. Naruszenie pamięci.

0

Witam.
To mój pierwszy post na tym forum, więc proszę o wyrozumiałość.

Proszę o pomoc odnośnie poniższego programu, który docelowo ma tworzyć drzewo binarne rozmieszczające wpisy wg kolejności alfabetycznej.
Program kompiluje się bez ostrzeżeń. Jednak po uruchomieniu i wpisaniu odpowiednich danych (funkcja add) kompilator wywala błąd "Naruszenie ochrony pamięci (core dumped)" . Kompiluję i uruchamiam komendą gcc w terminalu najnowszego Ubuntu.
Przypuszczam, że błąd kryje się w okolicach 42 linijki, tam gdzie rekurencyjnie wywoływana jest funkcja insert. Gdy usuwam tę funkcję, program nie wywala naruszenia ochrony pamięci. Podejrzewam, że coś skopałem ze wskaźnikami. Funkcja add przekazuje funkcji insert wskaźnik "leaf". Jestem mocno początkujący w programowaniu, więc być może błąd leży zupełnie gdzie indziej.

Z góry dziękuję za pomoc.

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

#define ROZMIAR 20

struct wezel
{
  char nazwisko[ROZMIAR];
  char imie[ROZMIAR];
  int telefon1;
  int telefon2;
  struct wezel *left;
  struct wezel *right;
};

void add(struct wezel **leaf);
int alphabetical(char *tab1, char *tab2 );
void insert(char *P_Nazwisko, char *P_Imie, int P_Telefon1, int P_Telefon2, struct wezel **leaf);

void insert(char *P_Nazwisko, char *P_Imie, int P_Telefon1, int P_Telefon2, struct wezel **leaf)
{
 
  if( *leaf == 0 )
  {
    int i;
    
    *leaf = (struct wezel*)malloc(sizeof(struct wezel));
    for(i=0;P_Nazwisko[i]!='\0';i++)
      (*leaf)->nazwisko[i] = P_Nazwisko[i];
    for(i=0;P_Imie[i]!='\0';i++)
      (*leaf)->imie[i] = P_Imie[i];
    (*leaf)->telefon1 = P_Telefon1;
    (*leaf)->telefon2 = P_Telefon2;
    
    (*leaf)->left = 0;  //ustawiam dzieci na NULL
    (*leaf)->right = 0;
  }
  
  if ( alphabetical( (*leaf)->nazwisko, P_Nazwisko ) == 1 ) printf("a");
    insert(P_Nazwisko, P_Imie, P_Telefon1, P_Telefon2, &(*leaf)->left);
  if ( alphabetical( (*leaf)->nazwisko, P_Nazwisko ) == 0 )
    insert(P_Nazwisko, P_Imie, P_Telefon1, P_Telefon2, &(*leaf)->right);     //TU JEST PROBLEM, prawdopowdobnie wskaźnik leaf
  
}

int alphabetical(char *tab1, char *tab2 )
{
  int k;
  
  for(k=0; tab1[k]!='\0' && tab2[k]!='\0';k++)
  {
    if( tab1[k] > tab2[k] )
      return 0;
    if( tab1[k] < tab2[k] )
      return 1;
  }
  
  if( tab1[k] == '\0' )
    return 1;
  if( tab2[k] == '\0' )
    return 0;
  else 
    return 0;
}
    
  

void add(struct wezel **leaf)
{
  char last_name[ROZMIAR], first_name[ROZMIAR];
  int telephone1, telephone2,a ;
  
  printf("Nazwisko: ");
  fgets(last_name, ROZMIAR, stdin);
  printf("Imie: ");
  fgets(first_name, ROZMIAR, stdin);
  
  scanf("%d", &telephone1);
  scanf("%d", &telephone2);
  
   
  
  insert(last_name, first_name, telephone1, telephone2, leaf);
}

    

int main()
{
  struct wezel *nowy;
 add(&nowy);
 return 0;
}
1

Twoje "nowy" w main to tylko wskaźnik bez zaalokowanej pamięci.

2

struct wezel *nowy=NULL;

0

Ustawiłem "nowy" na NULL'a i poprawiłem przypadkowy błąd w instrukjcji if (linijka 39).
@Shalom: Czy na pewno muszę allokować "nowy" w main'ie? Wydaje mi się, że 'nowy' powinien allokować się w funkcji insert, gdy drzewo dojdzie do pustego pola,

Teraz kod wygląda tak:

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

#define ROZMIAR 20

struct wezel
{
  char nazwisko[ROZMIAR];
  char imie[ROZMIAR];
  int telefon1;
  int telefon2;
  struct wezel *left;
  struct wezel *right;
};

void add(struct wezel **leaf);
int alphabetical(char *tab1, char *tab2 );
void insert(char *P_Nazwisko, char *P_Imie, int P_Telefon1, int P_Telefon2, struct wezel **leaf);

void insert(char *P_Nazwisko, char *P_Imie, int P_Telefon1, int P_Telefon2, struct wezel **leaf)
{
 
  if( *leaf == 0 )
  {
    int i;
    
    *leaf = (struct wezel*)malloc(sizeof(struct wezel));
    for(i=0;P_Nazwisko[i]!='\0';i++)
      (*leaf)->nazwisko[i] = P_Nazwisko[i];
    for(i=0;P_Imie[i]!='\0';i++)
      (*leaf)->imie[i] = P_Imie[i];
    (*leaf)->telefon1 = P_Telefon1;
    (*leaf)->telefon2 = P_Telefon2;
    
    (*leaf)->left = 0;  //ustawiam dzieci na NULL
    (*leaf)->right = 0;
  }
  
  if ( alphabetical( (*leaf)->nazwisko, P_Nazwisko ) == 1 )
    insert(P_Nazwisko, P_Imie, P_Telefon1, P_Telefon2, &(*leaf)->left);
  if ( alphabetical( (*leaf)->nazwisko, P_Nazwisko ) == 0 )
    insert(P_Nazwisko, P_Imie, P_Telefon1, P_Telefon2, &(*leaf)->right);     //TU JEST PROBLEM, prawdopowdobnie wskaźnik leaf
  
}

int alphabetical(char *tab1, char *tab2 )
{
  int k;
  
  for(k=0; tab1[k]!='\0' && tab2[k]!='\0';k++)
  {
    if( tab1[k] > tab2[k] )
      return 0;
    if( tab1[k] < tab2[k] )
      return 1;
  }
  
  if( tab1[k] == '\0' )
    return 1;
  if( tab2[k] == '\0' )
    return 0;
  else 
    return 0;
}
    
  

void add(struct wezel **leaf)
{
  char last_name[ROZMIAR], first_name[ROZMIAR];
  int telephone1, telephone2,a ;
  
  printf("Nazwisko: ");
  fgets(last_name, ROZMIAR, stdin);
  printf("Imie: ");
  fgets(first_name, ROZMIAR, stdin);
  
  scanf("%d", &telephone1);
  
  scanf("%d", &telephone2);
  scanf("%d", &a);printf("TU");
   
  
  insert(last_name, first_name, telephone1, telephone2, leaf);
}

    

int main()
{
  struct wezel *nowy=NULL;
 add(&nowy);
 return 0;
}

 

1 użytkowników online, w tym zalogowanych: 0, gości: 1