2017-01-24 11 views
1

Я пишу программу C, чтобы найти наиболее частой n-грамм в определенной строке.Не удается найти утечку по алгоритму n-граммов

N-грамм является

непрерывной последовательностью из п элементов из заданной последовательности текста

Тем не менее, у меня есть Сегментация Сбой в функции most_freq_ngram.

Параметров, в следующем порядке:

  • текст, из которого я хочу, чтобы вычислить ngrams
  • Количества символов в тексте
  • Размера ngrams я хочу вычислить
  • указатель на строку для наиболее частых н-грамм

Вот мой код:

#include <stdlib.h> 
#include <ctype.h> 
#include <stdio.h> 
#include <stdarg.h> 
#include <errno.h> 

typedef struct nodo_t{ 
    char* gram; 
    int count; 
    struct nodo_t * next; 
} nodo_t; 

typedef struct linked_list{ 
    nodo_t * head; 
} linked_list; 

int compare_arrays(char * igram, char * list_gram, size_t ngram_len){ 

    int i; 
    for(i=0;i<ngram_len;i++){ 
     if(tolower(list_gram[i]) != tolower(igram[i])) return 0; 
    } 

    return 1; 
} 

void copy_array(char * igram, char * list_gram, size_t ngram_len){ 
    int i; 
    for(i=0;i<ngram_len;i++) 
     list_gram[i] = tolower(igram[i]); 
} 

void add_gram(char * igram, linked_list * list, size_t ngram_len){ 
    if(list == NULL){ 
     list = malloc(sizeof(linked_list)); 
     nodo_t* head = malloc(sizeof(nodo_t)); 
     head->count = 1; 
     head->next = NULL; 

     head->gram = malloc(ngram_len * sizeof(char)); 

     int i; 
     for(i=0;i<ngram_len;i++) 
      head->gram[i] = igram[i]; 
     list->head = head; 
    }else{ 
     nodo_t * sent = list->head; 
     int found = 0; 
     while(sent->next != NULL && !found){ 
      //Check every element, otherwise add to que 
      int same = compare_arrays(igram, sent->gram, ngram_len); 
      if(same){ 
       sent->count++; 
       found = 1; 
      } 
      sent = sent->next; 
     } 

     if(!found){ 
      sent->next = malloc(sizeof(nodo_t)); 
      sent = sent->next; 
      sent->next = NULL; 
      sent->count = 1; 
      copy_array(igram, sent->gram, ngram_len); 
     } 
    } 
} 

void most_freq_ngram(const char* text, size_t text_len, size_t ngram_len, char** ngram){ 
    int i; 
    linked_list * list = NULL; 

    for(i=0;i<text_len - ngram_len +1;i++){ 
     char igram[ngram_len+1]; 
     int j; 

     int temp_i = i; 
     for(j=0;j<ngram_len;j++){ 
      igram[j] = text[temp_i]; 
      temp_i++; 
     } 

     igram[ngram_len] = '\0'; 
     add_gram(igram, list, ngram_len); 
    } 


    //Check list for most frequent element 
    char * most_frequent = malloc(ngram_len * sizeof(char)); 
    int frequency = 0; 

    nodo_t * sent = list->head; 

    if(sent == NULL){ 
     int i; 
     for(i=0;i<ngram_len;i++) 
      most_frequent[i] = '\0'; 
     return; 
    } 

    while(sent->next != NULL){ 
     if(sent->count > frequency){ 
      copy_array(sent->gram, most_frequent, ngram_len); 
      frequency = sent->count; 
     } 
    } 

    *ngram = most_frequent; 

    return ; 
} 

int main(){ 
    size_t ngram_len = 2; 
    char *ngram = malloc((ngram_len+1) * sizeof(char)); 

    size_t text_len = 5; 

    const char text[6] = {'a','a','a','a','a', '\0'}; 

    most_freq_ngram(text, text_len, ngram_len, &ngram); 

    return 0; 
} 
+0

Ваше название вопроса относится к «утечкам», тогда как текст вашего вопроса жалуется на ошибку сегментации. В любом случае вы не предоставляете полезной информации из сеанса отладки, кроме имени функции, в которой произошел segfault. – rici

+0

'{'a', 'a', 'a', 'a', 'a', '\ 0'}' is '" aaaaa "'. – DyZ

ответ

0

Ваша функция void add_gram(char * igram, linked_list * list, size_t ngram_len) не изменяет list. Он изменяет копию list. Оригинал list в most_freq_ngram остается неизменным (указатель NULL), который вызывает segfault в nodo_t * sent = list->head;. Измените второй параметр add_gram на linked_list ** list и перепишите функцию соответственно.