2013-11-09 2 views
0

필자의 bellard 함수를 실행하여 십만 자리까지 pi를 계산할 mpi 프로그램을 만들려고합니다. 내가 다음과 같은 오류가있는 프로그램을 실행할 때, 나는 온라인으로 검색하고 openMpi 웹 사이트에서 문제가 null 포인터 인 것처럼 보였지만 코드를 살펴 보았고 찾을 수없는 것 같다.MPI 프로그램 널 포인터

오류는 다음과 같습니다 신호 : 세그먼트 오류 (11) 신호 : 주소가 아닌 매핑 ​​(1) 주소 실패 : (전무)

사람이 널 포인터를 볼 수 있을까요? bellard 함수에서

#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <mpi/mpi.h> 

#define PRECISION 10000 


float minus_one,one,two,three,four,five,six,seven,eight,nine,ten, 
    thirty_two,sixty_four,two_five_six,one_zero_two_four, 
    two_pow_six,recip_two_pow_six; 


float *pi; 
int rank,size; 

void init(){ 
    printf("\nstarted init function"); 
    minus_one = -1.0; 
    one = 1.0; 
    two = 2.0; 
    three = 3.0; 
    four = 4.0; 
    five = 5.0; 
    six = 6.0; 
    seven = 7.0; 
    eight = 8.0; 
    nine = 9.0; 
    ten = 10.0; 
    thirty_two = 32.0; 
    sixty_four = 64.0; 
    two_five_six = 256.0; 
    one_zero_two_four = 1024.0; 
    two_pow_six = pow(two,6); 
    recip_two_pow_six = one/two_pow_six; 

    pi = 0; 
    printf("\nended init function"); 
    return; 
} 

float *bellard(int start, int end,int rank){ 
    float *terms; 
    float t,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12, 
     t13,t14,t15,t16,t17,tx,ty,tz; 

    int offset = rank; 
    double start_k = start; 
    double end_k = end; 
    start_k = offset * (PRECISION /size); 
    end_k = (offset+1) * (PRECISION/size); 
    terms=0; 

    int k = start_k; 

    while((k<PRECISION) && (k<end_k)){ 
     t1 = k; 
     t2 = t1*ten; 
     t3 = t2+one; 
     t4 = two_five_six/t3; 
     t5 = t2+nine; 
     t6 = one/t5; 
     t7 = t2+three; 
     t8 = sixty_four/t7; 
     t9 = four*t1; 
     t10 = t9+one; 
     t11 = thirty_two/t10; 
     t12 = t2+five; 
     t13 = four/t12; 
     t14 = t2+seven; 
     t15 = four/t14; 
     t16 = t9+three; 
     t17 = one+t16; 

     t = t4+t6; 
     t = t-t8; 
     t = t-t11; 
     t = t-t13; 
     t = t-t15; 
     t = t-t17; 

     tx = pow(minus_one,k); 
     ty = pow(one_zero_two_four,k); 
     tz = tx/ty; 
     *terms = tz*t; 

     //pi = pi+terms; 
     k = k+1; 
    } 
     return terms; 
} 

int main(int argc, char** argv){ 


    int i; 
    MPI_Status status; 
    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    int elementsCount = 10000/(size-1); 
    float *workerPi; 
    float *tmpPi=0; 

    init(); //initialise variables 
    printf("\nim here 1"); 
    if(rank == 0) 
    { 
     for(i=1; i < size; i++){ 
      printf("\nin recv loop");   
      MPI_Recv(tmpPi,PRECISION,MPI_FLOAT,i,1,MPI_COMM_WORLD,&status); 
      *pi=*pi+*tmpPi; 
     } 
    }else{ 

     //int i; 

     int start,end,slice,workers; 
     workerPi = malloc(sizeof(int)*elementsCount); 
     workers = size-1; 
     slice = 10000/workers; 
     start = (rank-1)*slice; 
     end = start+slice; 

     printf("\nWorker %d processing data %d to %d\n",rank,start,end); 

     workerPi = bellard(start,end,rank); 
     printf("\nworker finished pi"); 

     MPI_Send(workerPi,slice,MPI_FLOAT,0,1,MPI_COMM_WORLD); 
     printf("\nworker sent stuff"); 

    } 

    MPI_Finalize(); 

    return 0; 
} 

답변

2

termsfloat

float *terms; 

포인터로 선언 아래

terms=0; 

몇 줄의 끝 부분 (일명 null)는 0으로 초기화 while 루프는 참조 해제됩니다.

*terms = tz*t; 

진술 *terms은 널 포인터 참조 해제이며 충돌합니다. 본질적으로 tz*t의 결과를 유효한 메모리 주소가 아닌 메모리 주소 0에 저장하려고합니다.

해결 방법은 termsfloat으로 선언하고 float (float*)에 대한 포인터가 아닌 것으로 선언 한 것일 수 있습니다.