2016-12-14 7 views
-3

Я пытаюсь сделать симуляцию ebola с помощью pthreads. Все работало отлично, вплоть до семафоров. Я получаю эту ошибку при компиляции кода:Ошибка при компиляции кода «double free or corrupt (out)» с использованием потоков в C?

*** Error in `./ebola_serial': double free or corruption (out): 0x00007f49700008c0 *** 
    *** Error in `======= Backtrace: ========= 
    /lib64/libc.so.6(+0x7238e)[0x7f49868f038e] 
    ./ebola_serial/lib64/libc.so.6(+0x7a0c8)[0x7f49868f80c8] 
    ': /lib64/libc.so.6(cfree+0x48)[0x7f49868fb798] 
    double free or corruption (out)/lib64/libc.so.6(fclose+0x113)[0x7f49868e6473] 
    ./ebola_serial[0x401717] 
    /lib64/libpthread.so.0(+0x75bd)[0x7f4986c395bd] 
    : 0x/lib64/libc.so.6(clone+0x6d)[0x7f498697562d] 
    ======= Memory map: ======== 
    00007f49700008c000400000-00402000 r-xp 00000000 08:01 802698        /home/name/Desktop/try ca/ebola_serial 
    00601000-00602000 r--p 00001000 08:01 802698        /home/name/Desktop/try ca/ebola_serial 
    00602000-00603000 rw-p 00002000 08:01 802698        /home/name/Desktop/try ca/ebola_serial 
    00603000-009d3000 rw-p 00000000 00:00 0 
    01b96000-01bb7000 rw-p 00000000 00:00 0         [heap] 
    7f4970000000-7f4970021000 rw-p 00000000 00:00 0 
    7f4970021000-7f4974000000 ---p 00000000 00:00 0 
    7f4978000000-7f4978021000 rw-p 00000000 00:00 0 
    7f4978021000-7f497c000000 ---p 00000000 00:00 0 
    7f497c000000-7f497c021000 rw-p 00000000 00:00 0 
    7f497c021000-7f4980000000 ---p 00000000 00:00 0 
    7f4980000000-7f4980021000 rw-p 00000000 00:00 0 
    7f4980021000-7f4984000000 ---p 00000000 00:00 0 
    7f4984663000-7f4984679000 r-xp 00000000 08:01 131531      /usr/lib64/libgcc_s-4.9.2.so.1 
    7f4984679000-7f4984878000 ---p 00016000 08:01 131531      /usr/lib64/libgcc_s-4.9.2.so.1 
    7f4984878000-7f4984879000 r--p 00015000 08:01 131531      /usr/lib64/libgcc_s-4.9.2.so.1 
    7f4984879000-7f498487a000 rw-p 00016000 08:01 131531      /usr/lib64/libgcc_s-4.9.2.so.1 
    7f498487a000-7f498487b000 ---p 00000000 00:00 0 
    7f498487b000-7f498507b000 rw-p 00000000 00:00 0       [stack:7376] 
    7f498507b000-7f498507c000 ---p 00000000 00:00 0 
    7f498507c000-7f498587c000 rw-p 00000000 00:00 0 
    7f498587c000-7f498587d000 ---p 00000000 00:00 0 
    7f498587d000-7f498607d000 rw-p 00000000 00:00 0       [stack:7374] 
    7f498607d000-7f498607e000 ---p 00000000 00:00 0 
    7f498607e000-7f498687e000 rw-p 00000000 00:00 0       [stack:7373] 
    7f498687e000-7f4986a28000 r-xp 00000000 08:01 130947      /usr/lib64/libc-2.20.so 
    7f4986a28000-7f4986c28000 ---p 001aa000 08:01 130947      /usr/lib64/libc-2.20.so 
    7f4986c28000-7f4986c2c000 r--p 001aa000 08:01 130947      /usr/lib64/libc-2.20.so 
    7f4986c2c000-7f4986c2e000 rw-p 001ae000 08:01 130947      /usr/lib64/libc-2.20.so 
    7f4986c2e000-7f4986c32000 rw-p 00000000 00:00 0 
    7f4986c32000-7f4986c49000 r-xp 00000000 08:01 130973      /usr/lib64/libpthread-2.20.so 
    7f4986c49000-7f4986e48000 ---p 00017000 08:01 130973      /usr/lib64/libpthread-2.20.so 
    7f4986e48000-7f4986e49000 r--p 00016000 08:01 130973      /usr/lib64/libpthread-2.20.so 
    7f4986e49000-7f4986e4a000 rw-p 00017000 08:01 130973      /usr/lib64/libpthread-2.20.so 
    7f4986e4a000-7f4986e4e000 rw-p 00000000 00:00 0 
    7f4986e4e000-7f4986f53000 r-xp 00000000 08:01 130955      /usr/lib64/libm-2.20.so 
    7f4986f53000-7f4987152000 ---p 00105000 08:01 130955      /usr/lib64/libm-2.20.so 
    7f4987152000-7f4987153000 r--p 00104000 08:01 130955      /usr/lib64/libm-2.20.so 
    7f4987153000-7f4987154000 rw-p 00105000 08:01 130955      /usr/lib64/libm-2.20.so 
    7f4987154000-7f4987174000 r-xp 00000000 08:01 130940      /usr/lib64/ld-2.20.so 
    7f4987353000-7f4987356000 rw-p 00000000 00:00 0 
    7f498736d000-7f4987373000 rw-p 00000000 00:00 0 
    7f4987373000-7f4987374000 r--p 0001f000 08:01 130940      /usr/lib64/ld-2.20.so 
    7f4987374000-7f4987376000 rw-p 00020000 08:01 130940      /usr/lib64/ld-2.20.so 
    7ffce31e3000-7ffce3205000 rw-p 00000000 00:00 0       [stack] 
    7ffce320d000-7ffce320f000 r--p 00000000 00:00 0       [vvar] 
    7ffce320f000-7ffce3211000 r-xp 00000000 00:00 0       [vdso] 
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 
    Aborted 

Это мой код:

#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <semaphore.h> 
#include "timer.h" 
#define NUMROW 1000 
#define NUMCOL 1000 
#define NUMCOMP 1000000 
#define GEN 400 
#define THREAD_COUNT 4 

FILE *fp; 
char buffer[32]; 

int map[1000][1000]; 
int neighbours[8]; 
int nextGen; 
double chance; 

int tInfection = 0; 
int tHealthy = 0; 
int tDead = 0; 
int tRecovered = 0; 

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 

sem_t semaphores[THREAD_COUNT]; 

int barrCount1, 
barrCount2, totalDead, totalHealthy, totalInfection, totalRecovered, p; 
pthread_mutex_t barrier_mutex; 

void* mythread_func(void* rank) 
{ 
    long my_rank = (long) rank; 
    long i, j; 
    long my_row = NUMROW/THREAD_COUNT; 
    long my_col = my_row; 
    long my_first_i = my_row * my_rank; 
    long my_last_i = my_first_i + my_row - 1; 

    for (i = my_first_i; i < my_last_i; i++) 
    { 
    for (j = my_first_i; j < my_last_i; j++) 
    { 
     map[i][j] = 0; 
    } 
    } 

    int inf; 
    //infecting 5 random people 
    for (inf = 0; inf < 1; inf++) 
    { 
    double rand1 = floor(rand() % ((my_last_i + 1 - my_first_i) + my_first_i)); 
    double rand2 = floor(rand() % ((my_last_i + 1 - my_first_i) + my_first_i)); 

    int randFin1 = (int) rand1; 
    int randFin2 = (int) rand2; 

    map[randFin1][randFin2] = 1; 

    } 

    int k = 0; 
    long dest = (my_rank + 1) % THREAD_COUNT; 

    long genCount; 

    //loops of generation 
    for (genCount = 0; genCount < GEN; genCount++) 
    { 

    //mutex barrier--------------------------- 
    pthread_mutex_lock(&barrier_mutex); 
    barrCount1++; 
    pthread_mutex_unlock(&barrier_mutex); 
    while (barrCount1 < THREAD_COUNT) 
     ; 
    //---------------------------------------- 

    //looping through columns and rows 
    for (i = my_first_i; i < my_last_i; i++) 
    { 
     for (j = my_first_i; j < my_last_i; j++) 
     { 

     nextGen = 1; 

     //left neigbour 
     neighbours[0] = map[(i + NUMROW - 1) % NUMROW][j]; 

     //right neighbour 
     neighbours[1] = map[(i + NUMROW + 1) % NUMROW][j]; 

     //top neighbour 
     neighbours[2] = map[i][(j + NUMROW - 1) % NUMROW]; 

     //bottom neigbour 
     neighbours[3] = map[i][(j + NUMROW + 1) % NUMROW]; 

     //bottom left neighbour 
     neighbours[4] = 
      map[(i + NUMROW - 1) % NUMROW][(j + NUMROW + 1) % NUMROW]; 

     //bottom right neighbour 
     neighbours[5] = 
      map[(i + NUMROW + 1) % NUMROW][(j + NUMROW + 1) % NUMROW]; 

     //top left neighbour 
     neighbours[6] = 
      map[(i + NUMROW - 1) % NUMROW][(j + NUMROW - 1) % NUMROW]; 

     //top right neigbour 
     neighbours[7] = 
      map[(i + NUMROW + 1) % NUMROW][(j + NUMROW - 1) % NUMROW]; 

     int infections = 0; 
     int dead = 0; 

     for (p = 0; p < 8; p++) 
     { 
      if (neighbours[p] == 1) 
      { 
      infections++; 
      } 

      if (neighbours[p] == 2) 
      { 
      dead++; 
      } 
     } 

     if (infections > 0 && map[i][j] == 0) 
     { 
      chance = 20.0; 

      if (floor(rand() % 101) < chance) 
      { 
      //Person is infected 

      tInfection++; 
      tHealthy--; 

      map[i][j] = 1; 
      nextGen = 0; 
      } //end of infections if statement 
     } //end of chancing life 

     if (map[i][j] == 1 && nextGen) 
     { 
      chance = 10.0; 

      if (floor(rand() % 101) < chance) 
      { 
      //Person is dead 
      tDead++; 
      tHealthy--; 
      map[i][j] = 2; 
      } 
     } 

     if (map[i][j] == 1 && nextGen) 
     { 
      chance = 0.5; 

      if (floor(rand() % 101) < chance) 
      { 
      tRecovered++; 
      tDead--; 
      map[i][j] = 3; 
      } 
     } 
     } 
    } 
    } 

    pthread_mutex_lock(&mutex); 
    totalHealthy += tHealthy; 
    totalDead += tDead; 
    totalInfection += tInfection; 
    totalRecovered += tRecovered; 
    pthread_mutex_unlock(&mutex); 

    //mutex barrier--------------------------- 
    pthread_mutex_lock(&barrier_mutex); 
    barrCount2++; 
    pthread_mutex_unlock(&barrier_mutex); 
    while (barrCount2 < THREAD_COUNT) 
    ; 
    //---------------------------------------- 

    printf(
     "-------------------------------------------------\nThread %ld numbers:\nHealthy: %d\nDead: %d\nInfected: %d\nRecovered: %d\n", 
     my_rank, totalHealthy, totalDead, totalInfection, totalRecovered); 

    //every 50 generations create file with results 
    if (genCount % 50 == 0) 
    { 
    //incrementing file name 

    sem_post(&semaphores[dest]); 

    sem_wait(&semaphores[my_rank]); 

    snprintf(buffer, sizeof(char) * 32, "file%i.dat", k); 

    //open the file 
    fp = fopen(buffer, "r+"); 
    if (fp == NULL) 
    { 
     printf("I couldn't open file for writing.\n"); 
     exit(0); 
    } 

    int loop1, loop2; 

    //outputting the array into the file 
    for (loop1 = my_first_i; loop1 < my_last_i; loop1++) 
    { 
     for (loop2 = my_first_i; loop2 < my_last_i; loop2++) 
     { 
     fprintf(fp, "%d\t", map[loop1][loop2]); 
     } 
    } 

    //close the file 
    fclose(fp); 

    k++; 
    } 

    return NULL ; 
} 

int main() 
{ 

    //int map[1000][1000]; 
    //neighbours 
    int totalHealthy = 0; 
    int totalInfection = 0; 
    int totalDead = 0; 
    int totalRecovered = 0; 
    double chance = 20.0; 
    double start, finish, elapsed; 

    int i, j, g, inf; 
    int k = 0; 

    //--------------Seed For Random Numbers----------- 
    time_t t; 
    /* Inititializes random number generator*/ 
    srand((unsigned) time(&t)); 
    //------------------------------------------------ 

    printf("Ebola spreading...\n"); 

    //start timer------------------ 
    GET_TIME(start); 
    //----------------------------- 

    //Thread code---------------------------------------------------------------------- 
    long thread; 

    int semCount; 
    for (semCount = 0; semCount < THREAD_COUNT; semCount++) 
    { 
    sem_init(&semaphores[semCount], 0, 1); 
    } 

    pthread_t *mythread_handle; 

    mythread_handle = malloc(THREAD_COUNT * sizeof(pthread_t)); 

    for (thread = 0; thread < THREAD_COUNT; thread++) 
    { 
    pthread_create(&mythread_handle[thread], NULL, mythread_func, 
     (void *) thread); 
    } 

    for (thread = 0; thread < THREAD_COUNT; thread++) 
    { 
    pthread_join(mythread_handle[thread], NULL); 
    } 

    pthread_mutex_destroy(&mutex); 

    //---------------------------------------------------------------------------------- 
    //stop timer------------ 
    GET_TIME(finish); 

    elapsed = finish - start; 

    free(mythread_handle); 

    printf("Time elapsed: %e seconds\n", elapsed); 

    return 0; 

} 

Вот timer.h файл:

#ifndef _TIMER_H_ 
#define _TIMER_H_ 

#include <sys/time.h> 

/* The argument now should be a double (not a pointer to a double) */ 
#define GET_TIME(now) { \ 
     struct timeval t; \ 
     gettimeofday(&t, NULL); \ 
     now = t.tv_sec + t.tv_usec/1000000.0; \ 
    } 

#endif 

Любая помощь будет оценена. Спасибо

+0

Я хотел бы протестировать ваш код, но у меня нет файла '' timer.h ". Предоставьте код, который на самом деле компилируется. – Michi

+1

SO не является отладочной службой. Скомпилируйте с помощью символов, запустите код внутри отладчика, чтобы трассировать программы (программы) по очереди, проверяя значения соответствующих переменных, чтобы узнать, что действительно происходит. Если тогда возникает * конкретный * вопрос, не стесняйтесь возвращаться сюда. – alk

+1

Этот отступ действительно не читается. – alk

ответ

0

* fp - глобальная переменная, поэтому каждый therad инициализирует ее с помощью fopen и после завершения работы попытается ее закрыть. * fp делится между потоками (чего не должно быть), поэтому каждый поток перед выходом пытается закрыть дескриптор файла, хранящийся в * fp, и двойной свободный происходит, когда несколько потоков пытаются закрыть дескриптор файла, который уже закрыт другим потоком.

Вы должны установить * fp внутри функционального блока, чтобы сделать его локальным для каждого потока или добавить объявление __thread перед * fp, чтобы сделать его локальным для каждого экземпляра потока. __thread FILE * fp;

+0

Спасибо, вот и все. –

Смежные вопросы