我正在尝试编写一个用Xeon Phi编译的程序,它说有一个分段错误?我想是在尝试使用getc函数填充数组时。我已经将这些代码写成了几种不同的格式,我知道这可能不是最有效的,但是我需要测试它以确定它是否可以通过并行化来实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//#include <omp.h>
int main()
{
struct stat buf1;
struct stat buf2;
FILE *fp1, *fp2;
int ch1, ch2;
clock_t elapsed;
char fname1[40], fname2[40];
printf("Enter name of first file:");
fgets(fname1, 40, stdin);
while (fname1[strlen(fname1) - 1] == '\n')
{
fname1[strlen(fname1) -1] = '\0';
}
printf("Enter name of second file:");
fgets(fname2, 40, stdin);
while (fname2[strlen(fname2) - 1] == '\n')
{
fname2[strlen(fname2) -1] = '\0';
}
fp1 = fopen(fname1, "rb");
if (fp1 == NULL)
{
printf("Cannot open %s for reading\n", fname1);
exit(1);
}
fp2 = fopen(fname2, "rb");
if (fp2 == NULL)
{
printf("Cannot open %s for reading\n", fname2);
exit(1);
}
stat(fname1, &buf1);
size_t size1 = buf1.st_size;
stat(fname2, &buf2);
size_t size2 = buf2.st_size;
printf("Size of file 1: %zd\n", size1);
printf("Size of file 2: %zd\n", size2);
elapsed = clock(); // get starting time
size_t smallest = 0;
if(size1 < size2)
{
smallest = size1;
}
else
{
smallest = size2;
}
printf("Smallest Value: %zu\n", smallest);
size_t i, j, k;
size_t data[smallest];
size_t arry1[smallest];
size_t arry2[smallest];
unsigned long long counter = 0;
for(i = 0; i < smallest; i++)
{
data[i] = 1;
arry1[i] = getc(fp1);
arry2[i] = getc(fp2);
}
//#pragma omp for //reduction(+:counter)
for(k = 0; k < smallest; k++)
{
if((arry1[k] ^ arry2[k]) == 0)
{
counter+= data[k];
}
}
fclose (fp1); // close files
fclose (fp2);
float percent = (float)counter / (float)smallest * 100.0f;
printf("Counter: %zu Total: %zu\n", counter, smallest);
printf("Percentage: %.2f%\n", percent);
elapsed = clock() - elapsed; // elapsed time
printf("That took %.2f seconds.\n", (float)elapsed/CLOCKS_PER_SEC);
return 0;
}
提前感谢您的帮助!
答案 0 :(得分:2)
您不能声明一个在编译时未知的大小的数组:
int smallest;
smallest = .... // some computation
size_t data[smallest]; // this is wrong!
您应该使用malloc()
来实现这一目标:
size_t *data;
smallest = ... // whatever
data = malloc(smallest * sizeof(size_t));
答案 1 :(得分:2)
这个循环:
while (fname1[strlen(fname1) - 1] == '\n')
fname1[strlen(fname1) -1] = '\0';
如果该行为空(<{1}}),将读取字符串的开头。将"\n"
更改为while
。
另外,在声明VLA之前检查if
。
输出smallest > 0
的值可能很有见地,典型系统默认为1MB到8MB之间的堆栈大小,因此可能会导致堆栈溢出。你可以通过使用malloc来消除这种可能性,正如ocho88建议的那样(但没有虚假的演员):
smallest
我不确定为什么使用size_t *data = malloc(smallest * sizeof *data);
size_t *arry1 = malloc(smallest * sizeof *arry1);
size_t *arry2 = malloc(smallest * sizeof *arry2);
if ( !data || !arry1 || !arry2 )
// exit with out-of-memory error
来存储size_t
的结果。
如果这不能解决问题,那么确定哪条线是segfaulting是有用的。如果你无法使调试器工作,那么你可以输出(到stderr,或者用fflush输出到stdout)来找出它的起始位置。