weixin_44007090 2019-06-15 23:41 采纳率: 0%
浏览 121

关于下列代码运行的问题。

请问为什么这段代码运行会显示SIGSEGV?

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

int total=0;

struct index
{
    char word[51];
    struct index *ne;
};

struct conter
{
    char word[51];
    int n,pos[800000];
    struct conter *ne;
};

unsigned int hash(char *str)
{
    unsigned int ha=0;
    char *p;
    for(p=str; *p!='\0'; p++)
        ha = 37*ha + *p;
    return ha % 800000;
}

struct index *newindex(char* str)
{
    int i;
    struct index *p=(struct index*)malloc(sizeof(struct index));
    p->ne=NULL;
    for(i=0;str[i]!='\0';i++)
    {
        p->word[i]=str[i];
    }
    p->word[i]='\0';
    return p;
}

void append(struct index *head,struct index *newElement)
{
    struct index *p;
    for(p=head;p->ne!=NULL;p=p->ne);
    p->ne=newElement;
}

struct conter *newconter(char *str,int pos)
{
    struct conter *p=(struct conter *)malloc(sizeof(struct conter));
    p->ne=NULL;
    p->n=1;
    p->pos[0]=pos;
    strcpy(p->word,str);
    return p;
}

void count(struct conter *miss[],char *str,int pos)
{
    unsigned int h=hash(str);
    if(miss[h]==NULL)
    {
        miss[h]=newconter(str,pos);
        total++;
        return;
    }
    struct conter *p;
    for(p=miss[h];p!=NULL;p=p->ne)
    {
        if(!strcmp(str,p->word))
        {
            p->pos[p->n++]=pos;
            return;
        }
    }
    p=newconter(str,pos);
    total++;
    p->ne=miss[h];
    miss[h]=p;
}

int emp(const void *a, const void *b)
{
    struct conter** t1=(struct conter * *)a;
    struct conter** t2=(struct conter * *)b;
    int n=(*t1)->n-(*t2)->n;
    if(n)
        return -n;
    return strcmp((*t1)->word,(*t2)->word);
}

void printcon(struct conter * con, FILE * file)
{
    int i;
    fprintf(file,"%s %d %d", con->word, con->n, con->pos[0]);
    for (i = 1; i < con->n; i++)
    {
        fprintf(file, " %d", con->pos[i]);
    }
    fprintf(file, "\n");
}

int main() 
{
    FILE *in,*out;
    in=fopen("dictionary.txt","r");
    char temp[51];
    char t;
    struct index *words[800000];
    struct conter *miss[800000];
    int i,o,pos;
    unsigned int h;
    for(i=0;i<800000;i++)
    {
        words[i]=NULL;
        miss[i]=NULL;
    }
    while(!feof(in))
    {
        i=0;
        do
        {
            t=fgetc(in);
            if(t==EOF)
                break;
        }while(!((t>='A'&&t<='Z')||(t>='a'&&t<='z')));
        do
        {
            if(t>='A'&&t<='Z')
                t+='a'-'A';
            temp[i]=t;
            i++;
            t=fgetc(in);
        }while(((t>='A'&&t<='Z')||(t>='a'&&t<='z'))&&i<=50);
        temp[i]='\0';
        h=hash(temp);
        if(words[h]==NULL)
            words[h]=newindex(temp);
        else
            append(words[h],newindex(temp));
    }
    fclose(in);
    in=fopen("article.txt","r");
    pos=-1;
    while(!feof(in))
    {
        i=0;
        do
        {
            t=fgetc(in);
            pos++;
            if(t==EOF)
                break;
        }while(!((t>='A'&&t<='Z')||(t>='a'&&t<='z')));
        o=pos;
        do
        {
            if(t>='A'&&t<='Z')
                t+='a'-'A';
            temp[i]=t;
            i++;
            t=fgetc(in);
            pos++;
        }while(((t>='A'&&t<='Z')||(t>='a'&&t<='z'))&&i<=30);
        temp[i]='\0';
        h=hash(temp);
        if(words[h]==NULL)
        {
            count(miss,temp,o);
            continue;
        }
        struct index *p;
        for(p=words[h];p!=NULL;p=p->ne)
        {
            if(!strcmp(temp,p->word))
                break;
        }
        if(p==NULL)
        {
            count(miss,temp,o);
        }
    }
    fclose(in);
    out=fopen("misspelling.txt","w");
    i=0;
    o=0;
    struct conter *a;
    struct conter **missa=(struct conter * *)malloc(sizeof(struct conter*)*total);
    for(i=0;i<10000;i++)
    {
        a=miss[i];
        while(a!=NULL)
        {
            missa[o++]=a;
            a=a->ne;
        }
    }
    qsort(missa,total,sizeof(struct conter*),emp);
    for(i=0;i<total;i++)
    {
        printcon(missa[i],out);
    }
    fclose(out);
    return 0;
}
  • 写回答

1条回答 默认 最新

  • 芣苢的成长之路 2023-07-03 19:00
    关注

    以下引用自GPT的回答:
    这段代码中的SIGSEGV错误是由于内存访问越界引起的。在程序的最后,你定义了一个大小为totalmissa数组,然后使用qsort对其进行排序。但是,你没有为total变量赋值,因此missa数组的大小未知。接着,在for循环中,你遍历了800,000个miss数组元素,这会导致访问missa数组时越界。

    为了解决这个问题,你需要在程序中添加代码,将total变量赋值为实际的值。在count函数中,每当你添加一个新的conter节点时,你可以增加对total的计数。修改后的代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <string.h>
    
    int total = 0;
    
    struct index
    {
        char word[51];
        struct index *ne;
    };
    
    struct conter
    {
        char word[51];
        int n, pos[800000];
        struct conter *ne;
    };
    
    unsigned int hash(char *str)
    {
        unsigned int ha = 0;
        char *p;
        for (p = str; *p != '\0'; p++)
            ha = 37 * ha + *p;
        return ha % 800000;
    }
    
    struct index *newindex(char *str)
    {
        int i;
        struct index *p = (struct index *)malloc(sizeof(struct index));
        p->ne = NULL;
        for (i = 0; str[i] != '\0'; i++)
        {
            p->word[i] = str[i];
        }
        p->word[i] = '\0';
        return p;
    }
    
    void append(struct index *head, struct index *newElement)
    {
        struct index *p;
        for (p = head; p->ne != NULL; p = p->ne);
        p->ne = newElement;
    }
    
    struct conter *newconter(char *str, int pos)
    {
        struct conter *p = (struct conter *)malloc(sizeof(struct conter));
        p->ne = NULL;
        p->n = 1;
        p->pos[0] = pos;
        strcpy(p->word, str);
        return p;
    }
    
    void count(struct conter *miss[], char *str, int pos)
    {
        unsigned int h = hash(str);
        if (miss[h] == NULL)
        {
            miss[h] = newconter(str, pos);
            total++;
            return;
        }
        struct conter *p;
        for (p = miss[h]; p != NULL; p = p->ne)
        {
            if (!strcmp(str, p->word))
            {
                p->pos[p->n++] = pos;
                return;
            }
        }
        p = newconter(str, pos);
        total++;
        p->ne = miss[h];
        miss[h] = p;
    }
    
    int emp(const void *a, const void *b)
    {
        struct conter **t1 = (struct conter **)a;
        struct conter **t2 = (struct conter **)b;
        int n = (*t1)->n - (*t2)->n;
        if (n)
            return -n;
        return strcmp((*t1)->word, (*t2)->word);
    }
    
    void printcon(struct conter
    
     *con, FILE *file)
    {
        int i;
        fprintf(file, "%s %d %d", con->word, con->n, con->pos[0]);
        for (i = 1; i < con->n; i++)
        {
            fprintf(file, " %d", con->pos[i]);
        }
        fprintf(file, "\n");
    }
    
    int main()
    {
        FILE *in, *out;
        in = fopen("dictionary.txt", "r");
        char temp[51];
        char t;
        struct index *words[800000];
        struct conter *miss[800000];
        int i, o, pos;
        unsigned int h;
        for (i = 0; i < 800000; i++)
        {
            words[i] = NULL;
            miss[i] = NULL;
        }
        while (!feof(in))
        {
            i = 0;
            do
            {
                t = fgetc(in);
                if (t == EOF)
                    break;
            } while (!((t >= 'A' && t <= 'Z') || (t >= 'a' && t <= 'z')));
            do
            {
                if (t >= 'A' && t <= 'Z')
                    t += 'a' - 'A';
                temp[i] = t;
                i++;
                t = fgetc(in);
            } while (((t >= 'A' && t <= 'Z') || (t >= 'a' && t <= 'z')) && i <= 50);
            temp[i] = '\0';
            h = hash(temp);
            if (words[h] == NULL)
                words[h] = newindex(temp);
            else
                append(words[h], newindex(temp));
        }
        fclose(in);
        in = fopen("article.txt", "r");
        pos = -1;
        while (!feof(in))
        {
            i = 0;
            do
            {
                t = fgetc(in);
                pos++;
                if (t == EOF)
                    break;
            } while (!((t >= 'A' && t <= 'Z') || (t >= 'a' && t <= 'z')));
            o = pos;
            do
            {
                if (t >= 'A' && t <= 'Z')
                    t += 'a' - 'A';
                temp[i] = t;
                i++;
                t = fgetc(in);
                pos++;
            } while (((t >= 'A' && t <= 'Z') || (t >= 'a' && t <= 'z')) && i <= 30);
            temp[i] = '\0';
            h = hash(temp);
            if (words[h] == NULL)
            {
                count(miss, temp, o);
                continue;
            }
            struct index *p;
            for (p = words[h]; p != NULL; p = p->ne)
            {
                if (!strcmp(temp, p->word))
                    break;
            }
            if (p == NULL)
            {
                count(miss, temp, o);
            }
        }
        fclose(in);
        out = fopen("misspelling.txt", "w");
        i = 0;
        o = 0;
        struct conter *a;
        struct conter **missa = (struct conter **)malloc(sizeof(struct conter *) * total);
        for (i = 0; i < 800000; i++)
        {
            a = miss[i];
            while (a != NULL)
            {
                missa[o++] = a;
                a = a->ne;
            }
        }
        qsort(missa, total, sizeof(struct conter *
    
    ), emp);
        for (i = 0; i < total; i++)
        {
            printcon(missa[i], out);
        }
        fclose(out);
        return 0;
    }
    

    这样,missa数组的大小就会正确地与total相对应,并且不会导致内存访问越界错误。

    评论

报告相同问题?

悬赏问题

  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序
  • ¥15 onvif+openssl,vs2022编译openssl64