首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

请问:这个代码的segmentation fault 在哪里

2013-11-12 
请教:这个代码的segmentation fault 在哪里?我做了一个代码,预期功能是从两个文件list1.txt和list2.txt中

请教:这个代码的segmentation fault 在哪里?
    我做了一个代码,预期功能是从两个文件list1.txt和list2.txt中读取中文名单,然后从list2中找出list1里不存在的名字。每个名字占一行,由于是从excel拷贝过来到text中的,所以名字后面有个TAB。但这个代码运行后总是出现segmentation fault的提示。请问哪里出现了问题,谢谢!

// compareing name lists

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

#define SIZE 60
#define MAX  20

int main(void)
{
    char names_1[SIZE][MAX];
    char names_2[SIZE][MAX];
    char * pnames_1[SIZE], * pnames_2[SIZE];  //用以分别指向names_1[SIZE][MAX]和names_2[SIZE][MAX]
    char nms_1[SIZE][MAX];                 //用以装载names_1[SIZE][MAX]的每一串去掉尾部的TAB后的新串
    char nms_2[SIZE][MAX];                 //用于names_2[SIZE][MAX],功能同上
    char * pnms_1[SIZE], * pnms_2[SIZE];   //用以分别指向nms_1[SIZE][MAX]和nms_2[SIZE][MAX]
    char * fnd[SIZE];                       //用以装载找到的串
    int cnt_1 = 0, cnt_2 = 0, cnt_fnd = 0;
    int i;
    FILE *fp1, *fp2, *fp3;

    if((fp1 = fopen("list1.txt", "r")) == NULL)
    {
        fputs("Error reading "listing1.txt".", stderr);
        exit(1);
    }
    if((fp2 = fopen("list2.txt", "r")) == NULL)
    {
        fputs("Error reading "listing2.txt".", stderr);
        exit(1);
    }
    if((fp3 = fopen("results.txt", "w")) == NULL)
    {
        fputs("Error writing "results.txt".", stderr);
        exit(1);
    }
    while(cnt_1 <= SIZE && fgets(names_1[cnt_1], MAX, fp1) != NULL)
    {
        pnames_1[cnt_1] = names_1[cnt_1];
        pnms_1[cnt_1] = nms_1[cnt_1];
        cnt_1++;
    }
    while(cnt_2 <= SIZE && fgets(names_2[cnt_2], MAX, fp2) != NULL)
    {
        pnames_2[cnt_2] = names_2[cnt_2];
        pnms_2[cnt_2] = nms_2[cnt_2];
        cnt_2++;
    }

    for(i = 0; i < cnt_1; i++)
    {
        while(*(pnames_1[i]) && !isspace(*pnames_1[i]))
        {
            *pnms_1[i] = *pnames_1[i];  //将names_1[i]中的非空格符字符装载到nms_1[i]中
            pnames_1[i]++;
            pnms_1[i]++;
        }
        * pnms_1[i] = '\0';             //让nms_1[i]成为字符串
    }
    for(i = 0; i < cnt_2; i++)
    {


        while(*(pnames_2[i]) && !isspace(*pnames_2[i]))
        {
            *pnms_2[i] = *pnames_2[i];
            pnames_2[i]++;
            pnms_2[i]++;
        }
        * pnms_2[i] = '\0';
    }
    if(cnt_1 >= cnt_2)  //如果list1.txt中的名字数目多过list2.txt中的就用list1.txt中的名字与list2.txt
    {                   //中的名字进行比较
        for(i = 0; i < cnt_1; i++)
            if(strcmp(pnms_2[i], pnms_1[i]) != 0)
            {
                fnd[i] = pnms_1[i];   //将找到的不同名字串的地址赋予fnd[i]


                cnt_fnd++;
            }
    }
    else
    {
        for(i = 0; i < cnt_2; i++)
            if(strcmp(pnms_1[i], pnms_2[i]) != 0)
            {
                fnd[i] = pnms_2[i];
                cnt_fnd++;
            }
    }
    if(cnt_fnd > 0)
    {
        for(i = 0; i < cnt_fnd; i++)
            fputs(fnd[i], fp3);          
        fprintf(fp3, "\n%d found.", cnt_fnd);
    }
    else
        fputs("\nNo results found.", fp3);
    printf("\n%d\n", cnt_fnd);
    puts("\nDone!");
    fclose(fp1);
    fclose(fp2);
    fclose(fp3);

    return 0;
}

C segmentation fault
[解决办法]
出现的问题的时候没有断住吗?
[解决办法]
segmentation fault非法读写内存

多为 
1 指针未初始化
2 数组越界
导致
[解决办法]
你自己设个断点看看,这个应该会的吧?自己跟进去,单步调试。
[解决办法]
数组访问越界:

while(cnt_1 <= SIZE && fgets(names_1[cnt_1], MAX, fp1) != NULL)
改为:
while(cnt_1 < SIZE && fgets(names_1[cnt_1], MAX, fp1) != NULL)


while(cnt_2 <= SIZE && fgets(names_2[cnt_2], MAX, fp2) != NULL)
改为:
while(cnt_2 < SIZE && fgets(names_2[cnt_2], MAX, fp2) != NULL)


另外建议在使用指针数组之前先初始化,例如:
memset(&pnames_1, 0, sizeof(pnames_1));

[解决办法]

 while(cnt_1 <= SIZE && fgets(names_1[cnt_1], MAX, fp1) != NULL)
    {
        pnames_1[cnt_1] = names_1[cnt_1]; 
      // 这里都没有分配内存的,你定义的数组指针的,有SIZE指针而已,但是每个指针都没有分配内存
    
        pnms_1[cnt_1] = nms_1[cnt_1];
   // cnt_1的值有是是不能等于cnt_1的,但是while是可以的,所以这里也可能导致越界的危险
        cnt_1++;
    }
    while(cnt_2 <= SIZE && fgets(names_2[cnt_2], MAX, fp2) != NULL)
    {
        //这里的错误和上面的类似。自己修改过来吧!每个数组指针,每个指针都分配内存过去
        pnames_2[cnt_2] = names_2[cnt_2];
        pnms_2[cnt_2] = nms_2[cnt_2];
        cnt_2++;
    }

[解决办法]
中文名字要考虑编码方式哦。 
[解决办法]
添加打印信息,看最后输出打印的地方在哪里,缩小问题范围,有助于分析;

for(i = 0; i < cnt_1; i++)
        for(j = 0; j < cnt_2; j++)
            if(strcmp(nms_1[i], nms_2[j]) == 0)
            {
                fnd[i] = nms_1[i];
                cnt_fnd++;
            }

这里面的fnd[i] = nms_1[i];改为:
fnd[cnt_fnd] = nms_1[i];

热点排行