Oppure

Loading
21/01/13 12:57
Dante.cpp

Compilo ed eseguo il seguente, in questa maniera:
$ cc main.c tree.c strg.c -o tree -g
$ ./tree hello haw are you fine and you fine 
Errore di segmentazione (core dump creato)
$


#include"tree.h"

/**
 * La funzione tree_marge, crea un nuovo nodo t0, avente come figli
 * i nodi t1 e t2. L'informazione della foglia(nodo) padre sarà il 
 * parametro s.
 * 
 */
Tree tree_merge( Str s, Tree t1, Tree t2 )
{                                                  
  Tree t0 = (Tree)malloc(sizeof(struct Tree))
    ;
  t0->left = t1;
  t0->right = t2;
  
  str_cpy( t0->word, s);
  
  return t0;
}

/**
 * Se l'albero t è vuoto, allora crea una foglia, altrimenti vengono comparate le due 
 * informazioni "s" e "tree_word(t)". Se s è minore allora, si procede ricorsivamente con
 * un'inserimento verso sinistra, mentre essendo s maggiore si procederà ricorsivamente
 * verso il ramo destro.
 * Questo metodo di inserimento genera un'albero avente le parole lessicograficamente
 * minori, in basso a sinistra e quelle maggiori in basso a destra.
 * 
 */
Tree tree_insert( Str s, Tree t)
{ 
  if( tree_isvoid(t) )                                 
    return tree_new_leaf(s);
  
  int flag = str_cmp( tree_word(t), s);
  
  if (flag > 0)                                  
    return tree_merge(tree_word(t), tree_insert(s, tree_left(t)), tree_right(t));
    
  else if (flag < 0)        
    return tree_merge(tree_word(t), tree_left(t), tree_insert(s, tree_right(t)));
  
  else 
    return t;
}


int main(int argc, char **argv)
{
  Tree dizionario = NULL;   

  int i;
  for(i=1;i<argc;i++)
    dizionario = tree_insert( argv[i] , dizionario )
      ;    
  tree_show(dizionario);
  
  return 0;
}


Analizzando con gdb non si ferma all'errore, inoltre anche se metto un break point in tree_insert(), l'esecuzione non si ferma appena lo incontra...
aaa
21/01/13 13:33
Ci mostri il file

"tree.h"

?
21/01/13 14:24
Dante.cpp
//tree.h

#define TREE

#ifndef STRG
  #include"strg.h"
#endif

#ifndef STDIO
  #include<stdio.h>
#endif

#ifndef STDLIB
  #include<stdlib.h>
#endif

#ifndef STDBOOL
  #include<stdbool.h>
#endif


struct Tree
{                                         
  Str word;                                     
  struct Tree *left, *right;                                                                                 
};

typedef struct Tree * Tree;


/**
 * Unisce due alberi.
 * 
 */
extern Tree tree_merge( Str, Tree, Tree );


/**
 * Alloca una nuova foglia, priva di figli.
 *
 */ 
extern Tree tree_new_leaf( Str );   


/**
 * Verifica che l'albero sia vuoto.
 * 
 */
extern int tree_isvoid(Tree );


/**
 * Restituiscono rispettivamente il figlio sinistro 
 * e destro di t.
 * 
 */
extern Tree tree_left( Tree );

extern Tree tree_right( Tree );


/**
 * Restituisce l'informazione del nodo t
 * 
 */
extern Str tree_word( Tree );

/**
 * Inserisce nell'albero t, la parola s in maniera ordinata.
 * 
 */
extern Tree tree_insert( Str , Tree );

/**
 * Restituiscono rispettivamente le stringhe lessicografficamente
 * ninore e maggiore.
 * 
 */
extern Str tree_min( Tree );

extern Str tree_max( Tree );


/**
 * Stampa sul terminane l'albero t.
 * 
 */
extern void tree_show( Tree );


Posto anche il file con le definizioni?
Ultima modifica effettuata da Dante.cpp 21/01/13 14:32
aaa
21/01/13 15:08
Devi postare tutto il sorgente in modo che possa essere ricompilato *senza errori* per poterlo provare.

Altrimenti ci si sta più tempo a capire il problema e non hai risposte.

In particolare, comunque, queste linee

struct Tree
{                                        
  Str word;                                    
  struct Tree *left, *right;                                                                                
};
 
typedef struct Tree * Tree;


mi sembrano assurde ... che senso ha chiamare la struttura e il nuovo tipo con lo stesso nome (Tree) ?
21/01/13 15:19
Dante.cpp
mmm, non hai torto, cosi è più bellino:
struct Leaf
{                                         
  Str word;                                     
  struct Leaf *left, *right;                                                                                 
};

typedef struct Leaf * Tree;


//tree.c

#ifndef TREE
 #include"tree.h"
#endif

/**
 * La funzione tree_marge, crea un nuovo nodo t0, avente come figli
 * i nodi t1 e t2. L'informazione della foglia(nodo) padre sarà il 
 * parametro s.
 * 
 */
Tree tree_merge( Str s, Tree t1, Tree t2 )
{                                                  
  Tree t0 = (Tree)malloc(sizeof(struct Leaf))
    ;
  t0->left = t1;
  t0->right = t2;
  
  str_cpy( t0->word, s);
  
  return t0;
}

/**
 * Alloca una nuova foglia, priva di figli.
 *
 */ 
Tree tree_new_leaf( Str s )
{
  return tree_merge( s, NULL, NULL )
    ;   
}

/**
 * Verifica che l'albero sia vuoto.
 * 
 */
int tree_isvoid(Tree t)
{
  if (t == NULL)                                                                   
    return true;
  else 
    return false;
}


/**
 * Restituiscono rispettivamente il figlio sinistro 
 * e destro di t.
 * 
 */
Tree tree_left( Tree t ){ return t->left; }

Tree tree_right( Tree t ){ return t->right; }


/**
 * Restituisce l'informazione del nodo t
 * 
 */
Str tree_word( Tree t ){ return t->word; }


/**
 * Se l'albero t è vuoto, allora crea una foglia, altrimnti vengono comparete le due 
 * informazioni s e tree_word(t). Se s è minore allora, si procede ricorsivamente con
 * un'inserimento verso sinistra, mentre essendo s maggiore si procederà ricorsivamente
 * verso il ramo destro.
 * Questo metodo di inserimento genera un'albero avente le parole lessicografficamente
 * minori in basso a sinistra e quelle maggiori in basso a destra.
 * 
 */
Tree tree_insert( Str s, Tree t)
{ 
  if( tree_isvoid(t) )                                 
    return tree_new_leaf(s);
  
  int flag = str_cmp( tree_word(t), s);
  
  if (flag > 0)                                  
    return tree_merge(tree_word(t), tree_insert(s, tree_left(t)), tree_right(t));
    
  else if (flag < 0)        
    return tree_merge(tree_word(t), tree_left(t), tree_insert(s, tree_right(t)));
  
  else 
    return t;
}

/**
 * Scorre l'albero dall'alto verso il basso a sinistra
 * cosi trovando l'informazione minore.
 * La funzione tree_max funzione in maniera analoga.
 * 
 */
Str tree_min( Tree t )
{                  
  if(tree_isvoid(tree_left(t))) 
    return tree_word(t);         
  else 
    return tree_min(tree_left(t));                   
}


Str tree_max( Tree t )
{
  if(tree_isvoid(tree_right(t))) 
    return tree_word(t);  
  else 
    return tree_max(tree_right(t));
}


/**
 * Stampa sul terminane l'albero t.
 * 
 */
void tree_show( Tree t )
{
  if (tree_isvoid(t) == false)
  { 
    tree_show(tree_left(t));
    printf("%s ", tree_word(t));
    tree_show(tree_right(t));
  }
}


//strg.h

#define STRG

#ifndef STDIO
  #include<stdio.h>
#endif

#ifndef STDLIB
  #include<stdlib.h>
#endif

#ifndef STRING
  #include<string.h>
#endif


typedef  char * Str;


/**
 * Dimensione massima delle stringhe gestite; se l'input
 * supera il limite la stringa viene tagliata, evitando 
 * di invadere zone di memoria adiacenti.
 * 
 */ 
#define MAX_CH 1024


/**
 * Alloca una vettore di MAX_CH+1 char, che potra contenere
 * una stringa di MAX_CH carateri, piu un byte per il caratere
 * di fine stringa.
 * 
 */
extern Str str_new_max();

/**
 * Alloca una vettore di nchar+1 char, che potra contenere
 * una stringa di nchar carateri, piu il fine stringa. Se
 * cerchiamo di allocare stringhe di lunghezza maggiore di MAX_CH, 
 * verrà restituito NULL.
 * 
 */
extern Str str_new( int );

/**
 * Copia la stringa s2 in s1, sino a un massiamo di MAX_CH
 * carateri, se la stringa di destinazione è troppo picola 
 * restituisce -1 altrimenti 0
 * 
 */
extern int str_cpy( Str, Str );

/**
 * Crea una coppia identica del parametro passato; se
 * l'input è maggiore di MAX_CH restiruisce NULL.
 * 
 */
extern Str str_twix( Str );

/**
 * Compara lesicografficamente due stringhe prive di spazzi. Restiruisce 
 * un valore negativo se s1< s2, 0 se s1 == s2 e un intero positivo se s1>s2.
 *
 */ 
extern int str_cmp( Str, Str );



//strg.c

#ifndef STRG
  #include"strg.h"
#endif

/**
 * Alloca una vettore di MAX_CH+1 char, che potra contenere
 * una stringa di MAX_CH carateri, piu un byte per il caratere
 * di fine stringa.
 * 
 */
Str str_new_max()
{
  return (Str) calloc( MAX_CH+1, sizeof(char))
    ;
}

/**
 * Alloca una vettore di nchar+1 char, che potra contenere
 * una stringa di nchar carateri, piu il fine stringa. Se
 * cerchiamo di allocare stringhe di lunghezza maggiore di MAX_CH, 
 * verrà restituito NULL.
 * 
 */
Str str_new( int nchar )
{
  Str out
    =
  nchar <= MAX_CH
    ?  
  (Str) calloc( nchar+1, sizeof(char))
    :
  (Str) NULL
    ;
    
  return out;
}

/**
 * Copia la stringa s2 in s1, sino a un massiamo di MAX_CH
 * carateri, se la stringa di sestinazione è troppo picola 
 * restituisce -1 altrimenti 0.
 * 
 */
int str_cpy( Str s1, Str s2)
{
  int flag 
    = 
  strlen(s2) <= strlen(s1) 
    ?
  0 : -1
    ;
    
  strncpy( s1, s2, MAX_CH);
  
  return flag;
}


/**
 * Crea una coppia identica del parametro passato; se l'input è maggiore di MAX_CH restiruisce NULL.
 * In questo caso non ha senso controllare le ecezzioni di str_cpy, dal momento che allocchiamo la 
 * stringa c, in funzione di strlen(s). 
 * 
 */
Str str_twix( Str s )
{
  Str c = str_new( strlen(s) );
  
  if( c != NULL )
    str_cpy(c,s);
    
  return c;
}


/**
 * Compara lesicografficamente due stringhe prive di spazzi. Restiruisce un valore negativo se s1< s2, 
 * 0 se s1 == s2 e un intero positivo se s1>s2.
 *
 */ 
int str_cmp( Str s1, Str s2 )
{
  return strncmp( s1, s2, MAX_CH )
    ;
}


Scusate la ridondanza dai commenti...
Ultima modifica effettuata da Dante.cpp 21/01/13 15:22
aaa