【问题标题】:Can't find leak on n-grams algorithm在 n-gram 算法上找不到泄漏
【发布时间】:2017-01-24 21:07:23
【问题描述】:

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

一个n-gram是一个

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

但是,我在函数 most_freq_ngram 中有一个分段错误。

参数依次为:

  • 我要从中计算 ngram 的文本
  • 文本中的字符数
  • 我要计算的 n-gram 的大小
  • 指向最常见 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;
}

【问题讨论】:

  • 您的问题标题指的是“泄漏”,而您的问题文本抱怨分段错误。无论如何,除了发生段错误的函数名称之外,您没有提供调试会话中的有用信息。
  • {'a','a','a','a','a', '\0'}"aaaaa"

标签: c linked-list segmentation-fault


【解决方案1】:

您的函数void add_gram(char * igram, linked_list * list, size_t ngram_len ) 不会更改list。它更改了list 的副本。 most_freq_ngram 中的原始 list 保持不变(一个 NULL 指针),这会导致 nodo_t * sent = list-&gt;head; 中的段错误。将add_gram的第二个参数改成linked_list ** list,并相应改写函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 2011-11-27
    • 2020-04-28
    相关资源
    最近更新 更多