【问题标题】:Segmentation fault (core dumped)...BMH Algorithm分段错误(核心转储)...BMH 算法
【发布时间】:2013-03-07 05:27:09
【问题描述】:

我正在尝试实现 Boyer Moore Horsepoole 算法。此代码是用 Turbo C++、Windows 编写的。有效。我必须在ubuntu中移植这个。

typedef struct skip_table
{
    char index;
    int value;
}skip_table;

void create_table(char*,int);
int discrete_char(char*,int);
int bm(char*, char*);
int lookup(char);
int check_EOF(char*,int);

skip_table *t1;
int tab_len;
FILE *fptr;

int main()
{
    time_t first, second;
    double time_spent;
    long int cnt=0;

    char *key_string,*buf,c; // String to be matched and text
    int i,key_len,text_len,def_shift_len,flag_match=0;

    gets(key_string);
    key_len=strlen(key_string);

    fptr=fopen("test_file.txt","r");
    first = clock();
    fseek(fptr,SEEK_SET,0);
    create_table(key_string,key_len);

    while(flag_match!=1)
    {
        fseek(fptr,100*cnt,0);
        fread(buf,100-key_len-1, 1, fptr);
        flag_match = bm(buf, key_string);
        cnt++;

    printf("\n%d",cnt);
     }
    second =clock();
time_spent=(double)(second-first)/CLOCKS_PER_SEC;

if(flag_match==1)
    printf("\n\nMatch Found in %lf seconds",time_spent);
else
    printf("\n\nMatch NOT Found in %lf seconds",time_spent);

    fclose(fptr);
    return 0;
}

int discrete_char(char* key_string,char* temp,int key_len)
{
    int i,j,count=1,flag=0;

for(i=1;i<key_len;i++)
{
    for(j=0; j<count; j++)
    {
        flag=0;
        if(temp[j] == key_string[i])
        {
            flag=1;
            break;
        }
    }
        if(flag!=1)
        {
            temp[count++]=key_string[i];
            flag=0;
        }
}

temp[count]='\0';
return count;
}

void create_table(char* key_string,int key_len)
{
    int i,j,k,max_index;
char *temp;
temp[0] = key_string[0];

tab_len=discrete_char(key_string,temp,key_len);
t1=(skip_table*)malloc((tab_len-1)*sizeof(skip_table));

for(i=0;i<tab_len;i++)
{
    for(j=0;j<key_len;j++)
    {
        if(temp[i]==key_string[j])
            max_index=j;
    }

    t1[i].index=temp[i];
    t1[i].value=key_len-max_index-1;

    printf("\n\n %c %d",t1[i].index,t1[i].value);
}
}

int bm(char* text, char* key_string)
{
int i_t, i_k, j,k, text_len, key_len, shift, count=0, flag_match=0;
int loop_count;

text_len = strlen(text);
key_len = strlen(key_string);
i_t=key_len;
i_k=key_len;

loop_count=0;

while(i_t<=text_len)
{
    if(count != key_len)
    {
        if(text[i_t-1]==key_string[i_k-1])
        {
            count++;
            i_t--;  i_k--;
            loop_count++;
        }
        else
        {
            if(loop_count>key_len)
            {
                i_t=i_t+lookup(text[i_t-1])+1;
                i_k=key_len;
                loop_count=0;
                continue;
            }
            shift = lookup(text[i_t-1]);
            if(shift<=0)
                shift=key_len;
            i_t = i_t+shift;
            i_k = key_len;
            count=0;
        }
    }
    else
    {
        flag_match =  1;
        break;
    }
}
return flag_match;
}

“int lookup(char index)”如果存在于“temp”中,则返回索引的相应值字段,否则返回-1。

这是我的全部代码。

【问题讨论】:

  • create_table() 是做什么的?添加定义..
  • 你确定你没有通过调用gets() 而没有溢出temp 没有边界检查?
  • 提示:使用调试选项(通常为-g)编译并链接。然后您将在valgrind 输出中获得出现问题的行号,这样更容易发现问题。
  • 您的代码在您未向我们展示的函数中崩溃。您希望我们如何为您调试?

标签: c memory-leaks segmentation-fault


【解决方案1】:

我并没有确切地看到出了什么问题,但这里有一些防御性编程技巧:

int main()
{
  // initialize all variables before use
  time_t first = 0, second = 0;
  double time_spent = 0.0;
  long int cnt=0;

  char *key_string = NULL;
  char *buf = NULL;
  char  c = '\0';  
  char temp[50] = {0};
  int i = 0,key_len=0,text_len=0,def_shift_len=0,flag_match=0;

// use fgets instead of gets, fgets allows you specify max length

  fgets(temp,sizeof(temp),stdin);
  key_len=strlen(temp);
  key_string = (char*) malloc(key_len+1);

// use strncpy or strcpy_s to specify max size
  strncpy(key_string, temp, sizeof(key_string));

  fptr = fopen("test_file.txt","r");

  first = clock();

// here arguments have wrong order, fseek takes origin as last arg:
  fseek(fptr,0,SEEK_SET);

// could be something in create_table, but you have not supplied it
  create_table(key_string,key_len);

当你在一个函数中有这么多变量时,你可以考虑将函数的一部分移到其他函数中

【讨论】:

  • 我同意使用fgets(); gets() 早已被遗忘。我看不出在这里使用strncpy() 的理由;您刚刚测量了字符串的长度,为该字符串和空值分配了足够的空间,因此不需要检查字符串副本。如果你建议memmove(key_string, temp, key_len+1)(或memcpy()),那么是的,肯定的。与此无关,strncpy(key_string, temp, sizeof(key_string));错误;应该是strncpy(key_string, temp, key_len+1);
  • 很好地发现了fseek() 的错误参数;你会得到更多的分数,因为它是不必要的,因为文件是在开始时打开读取的。
  • @JonathanLeffler 是的,我同意 abt strncpy,strcpy 很好,我已经编辑了答案。关于fseek 也是如此,尽管他之前所拥有的可能会导致问题 - 我也不确定他是否显示了所有代码。
  • 嘿,非常感谢大家..确实解决了这个问题..我想 Turbo C 是一个非常简单的工具,它不会检查这些故障..将来会小心..谢谢.. :)
【解决方案2】:

尝试在您的 valgrind 选项上使用 --track-origins=yes,正如输出所示,这可以帮助追踪未初始化变量的来源。

正如其他人所建议的那样,valgrind 报告的问题在 create_table 内部,所以也请发布代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-25
    • 2021-06-03
    相关资源
    最近更新 更多