Can';n-grams算法中的t-find漏洞

Can';n-grams算法中的t-find漏洞,c,linked-list,segmentation-fault,C,Linked List,Segmentation Fault,我正在编写一个C程序,以便在某个字符串中找到最频繁的n-gram 一个n克是一个 给定文本序列中n个项目的连续序列 但是,我在函数most\u freq\u ngram中有一个分段错误 这些参数依次为: 我要计算ngrams的文本 文本中的字符数 我要计算的n克的大小 指向最频繁n-gram的字符串的指针 这是我的密码: #include <stdlib.h> #include <ctype.h> #include <stdio.h> #include &

我正在编写一个C程序,以便在某个字符串中找到最频繁的n-gram

一个n克是一个

给定文本序列中n个项目的连续序列

但是,我在函数
most\u freq\u ngram
中有一个分段错误

这些参数依次为:

  • 我要计算ngrams的文本
  • 文本中的字符数
  • 我要计算的n克的大小
  • 指向最频繁n-gram的字符串的指针
这是我的密码:

#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;
}
#包括
#包括
#包括
#包括
#包括
类型定义结构节点{
字符*克;
整数计数;
结构节点*下一步;
}诺多!;
类型定义结构链接列表{
点头;
}链表;
int比较数组(字符*igram,字符*list\U gram,大小\U ngram\U len){
int i;
对于(i=0;不精确=NULL;
头部->克=malloc(ngram_len*sizeof(char));
int i;
对于(i=0;igram[i]=igram[i];
列表->头部=头部;
}否则{
nodo_t*sent=list->head;
int=0;
while(已发送->下一步!=NULL&&!已找到){
//检查每个元素,否则添加到que
int same=比较数组(igram,sent->gram,ngram-len);
如果(相同){
发送->计数++;
发现=1;
}
发送=发送->下一步;
}
如果(!找到){
发送->下一步=malloc(sizeof(nodo_t));
发送=发送->下一步;
发送->下一步=空;
发送->计数=1;
复制阵列(igram,发送->gram,ngram);
}
}
}
无效最频繁内存(常量字符*文本、大小文本、大小内存、字符**ngram){
int i;
链表*list=NULL;
对于(i=0;i计数>频率){
复制数组(发送->gram,最频繁,ngram-len);
频率=发送->计数;
}
}
*ngram=最频繁;
返回;
}
int main(){
尺寸随机长度=2;
char*ngram=malloc((ngram_len+1)*sizeof(char));
大小文本长度=5;
常量字符文本[6]={'a','a','a','a','a','a','a','0'};
最频繁的内存(文本、文本、内存和内存);
返回0;
}

您的函数
无效添加图(字符、链接列表、大小列表)
不会更改
列表
。它会更改
列表
的副本。
大多数频率的
中的原始
列表
保持不变(空指针),这会导致在
nodo\u t*sent=list->head;
中出现segfault。将
add\u gram
的第二个参数更改为
linked\u list**list
并相应地重写函数。

您的函数
void add\u gram(char*igram,linked\u list*list,size\t ngram)
不会更改
列表
。它会更改
列表
的副本。
大多数频率内存中的原始
列表
保持不变(空指针),这会导致在
nodo\u t*sent=list->head;
中出现segfault。将
add\u gram
的第二个参数更改为
linked\u list**list
并相应地重写函数。

您的问题标题指的是“泄漏”然而,您的问题的文本抱怨存在分段错误。在任何情况下,您都不会从调试会话中提供任何有用的信息,除了发生分段错误的函数的名称。
{'a'、'a'、'a'、'a'、'a'、'\0'}
“aaaaaaa”
。您的问题标题是“泄漏”然而,您的问题的文本抱怨存在分段错误。在任何情况下,您都不会从调试会话中提供任何有用的信息,除了发生分段错误的函数名。
{'a'、'a'、'a'、'a'、'a'、'\0'}
“aaaaaaa”