分段故障? getc函数和数组

时间:2014-07-24 21:10:52

标签: c segmentation-fault

我正在尝试编写一个用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;
}

提前感谢您的帮助!

2 个答案:

答案 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)来找出它的起始位置。