主要代码如下:
#pragma omp single
{
//printf("single start\n");
        blockNum=rowstr[lastrow-firstrow+1]/num_threads;
        tempNum=blockNum;
        nzStart[0]=0.0;
        for(i=0,j=1;i<lastrow-firstrow+1;i++)
                if(rowstr[i]>=tempNum)
                {
                        nzStart[j]=i;
                        tempNum+=blockNum;
                        j++;
                }
        nzStart[num_threads]=lastrow-firstrow+1;
//printf("single end,parallel start\n");
        for(i=0;i<=num_threads;i++)
                printf("nzstart[%d]=%d\n",i,nzStart[i]);
}
#pragma omp flush
//段错误发生在下面的循环中
#pragma omp for private(i,j)
for(k=0;k<num_threads;k++)
{
        //printf("one for, %d\n",omp_get_thread_num());
        for(i=nzStart[k];i<=nzStart[k+1];i++)
        {
                double sum=w[i];
                for(j=rowstr[i];j<rowstr[i+1];j++)
                {
                        int index=colidx[j];
                        sum=sum+a[j]*p[index];
                }
                w[i]=sum;//如果注释掉这行就不会出现段错误
        }
        //printf("one end, %d\n",omp_get_thread_num());
}

单个线程时,一般不出现段错误。多个线程有时有段错误,有时没有。