2012-04-22 80 views
0

我想学习C和MPI,这个程序计算n个浮点数的总和。但是我有一个错误:MPI,calloc和免费:

/home/xx/PRIMO/primo.exe:free():无效下一个大小(快):0x000000000109bda0 /home/xx/PRIMO/primo.exe:free():invalid下一个大小(快):0x00000000024fada0

是2天,我不知道该怎么转。这里所说的程序:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 
#include "mpi.h" 

#define HOST 0 
// prototypes 
void initialize(int argc, char *argv[]); 
float *create_array(int n); 
void data_scatter(float *numbers, float *numbers_loc, int packet_size, int rest); 
void validations(); 

// global vars 
int menum, nproc, namelen; 

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

    initialize(argc, argv); 
    if(menum == HOST) printf("Program started\n"); 
    if(menum == HOST) validations(); 

    // ****** Declaring variebles ****** 
    int n, tag, packet_size, rest, j, i; 
    float *numbers, *numbers_loc; 
    float sum = 0.0; 
    numbers_loc = (float*) calloc(packet_size, sizeof (float)); 
    MPI_Status info; 

    // ****** data distribution ****** 
    scanf("%d", &n); 
    if(menum == HOST) numbers = create_array(n); 

    MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); 
    double start_time = MPI_Wtime(); 

    packet_size = n/nproc; 
    rest = n % nproc; 
    if(menum < rest) ++packet_size; 

    data_scatter(numbers, numbers_loc, packet_size, rest); 

    // ****** partial sums, first level ****** 
    for(j = 0; j < packet_size; j++) { 
    sum += numbers_loc[j]; 
    } 
    free(numbers_loc); 

    // ****** iterating phase ****** 
    for(i = 0; i < log2(nproc); i++) { 

    int pow1 = (int) pow(2, i); 
    tag = pow1 + 15; 

    if((menum % pow1) == 0) { 

     int pow2 = (int) pow(2,i+1); 
     if((menum % pow2) == 0) { 

     float other_sum = 0; 
     MPI_Recv(&other_sum, 1, MPI_INT, menum + pow1, tag, MPI_COMM_WORLD, &info); 
     sum += other_sum; 

     } else { 

     MPI_Send(&sum, 1, MPI_INT, menum - pow1, tag, MPI_COMM_WORLD); 

     } 
    } 
    } 

    // ****** printing result ****** 
    if(menum == HOST) { 
    printf("TOTAL SUM: %.2f\n", sum); 
    } 

    double end_time = MPI_Wtime(); 
    double time = end_time - start_time; 
    double max = 0; 

    printf("%d time %f\n", menum, time); 
    MPI_Reduce(&time, &max, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); 
    if(menum == HOST) printf("%d max time %f\n", menum, max); 

    printf("Program terminated\n"); 
    MPI_Finalize(); 
    return 0; 
} 

void initialize(int argc, char *argv[]) { 

    MPI_Init(&argc,&argv); 
    MPI_Comm_rank(MPI_COMM_WORLD,&menum); 
    MPI_Comm_size(MPI_COMM_WORLD,&nproc); 

} 


float *create_array(int n) { 

    float sequenzial_sum = 0; 
    int i; 

    printf("Creating Array of dimension: %d\n", n); 

    float *array = (float*) calloc(n, sizeof(float)); 
    srand(time(NULL)); 

    for(i=0; i < n; i++) { 

     array[i] = ((float) rand())/ ((float) RAND_MAX); 
     sequenzial_sum += array[i]; 

     printf("-%f-", array[i]); 
    } 

    printf("\n"); 
    printf("Array creation terminated, sum = %.2f \n", sequenzial_sum); 

    return array; 
} 

void data_scatter(float *numbers, float *numbers_loc, int packet_size, int rest) { 
    MPI_Status info; 
    int start = 0, offset = packet_size, i, tag; 

    if(menum == HOST) { 

    memcpy(numbers_loc, numbers, packet_size * sizeof(float)); 
    for(i=1; i < nproc; i++) { 

     start += offset; 
     if(rest == i) --offset; 

     tag = 22 + i; 
     MPI_Send(&numbers[start], offset, MPI_INT, i, tag, MPI_COMM_WORLD); 

    } 

    free(numbers); 

    } else { 

    tag = 22 + menum; 
    MPI_Recv(numbers_loc, packet_size, MPI_INT, 0, tag, MPI_COMM_WORLD, &info); 

    } 

} 

void validations() { 

    if((fmod(log2(nproc), 1.0) != 0)) { 

    printf("CPU number must ne a power of 2\n"); 
    MPI_Abort(MPI_COMM_WORLD, -1); 

    } 

} 

回答

4
int n, tag, packet_size, rest, j, i; 
float *numbers, *numbers_loc; 
float sum = 0.0; 
numbers_loc = (float*) calloc(packet_size, sizeof (float)); 

我不知道如果我失去了一些东西,但packet_size使用没有正在此间初始化。与-Wall编译实际上警告你这一点。

-Wall也会警告您您缺少<time.h>头文件。

+2

我通常建议,对于新的代码,人们使用'-Wall -Wextra -Werror'。它可以帮助你解决这些问题,'-Werror'意味着你实际上解决了所有的警告(即使它们并不是真正的问题),以便在引入新问题时能够真正注意到这些警告。 – 2012-04-22 17:15:22

+0

非常感谢。我有点愚蠢:) – Antonio 2012-04-22 17:29:13

-1
// global vars 
`int menum, nproc, namelen;` 
// ****** Declaring variebles ****** 
// int n, tag, packet_size, rest, j, i; 

PACKET_SIZE没有定义,所以这将是垃圾值,不确定的行为,释放calloc不一定成功,100%

`numbers_loc = (float*) calloc(packet_size, sizeof (float));` 
`packet_size = n/nproc; 

` 全局变量NPROC将被初始化为0,并通过将某些号码0这应该会引发异常。

`rest = n % nproc;` 

以上声明也是不允许的。 我不知道是否有任何机制来剿上述错误,然后如果控制涉及到下面的语句

作为PACKET_SIZE是不确定的,numbers_loc分配与垃圾大小
`// ****** partial sums, first level ****** 
for(j = 0; j < packet_size; j++) { 
    sum += numbers_loc[j]; 
} ` 

numbers_loc将被破坏。 free(numbers_loc);

+3

请让答案可读... – 11684 2012-04-22 19:54:27