请教:这个代码的segmentation fault 在哪里?
我做了一个代码,预期功能是从两个文件list1.txt和list2.txt中读取中文名单,然后从list2中找出list1里不存在的名字。每个名字占一行,由于是从excel拷贝过来到text中的,所以名字后面有个TAB。但这个代码运行后总是出现segmentation fault的提示。请问哪里出现了问题,谢谢!
// compareing name listsC segmentation fault
#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;
}
[解决办法]
出现的问题的时候没有断住吗?
[解决办法]
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];