ошибка сегментации при использовании atoi

Мой код:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#define BUFFER_SIZE 5
#define TRUE 1
int numberOfLines ;
int sumCounter, subCounter, mulCounter, divCounter ;
int sumFileEnd, subFileEnd, mulFileEnd, divFileEnd ;
pthread_t *tid ;

clock_t begin, end;
double time_spent;

sem_t sumfull, sumEmpty ;
sem_t subfull, subEmpty ;
//sem_t mulfull, mulEmpty ;
//sem_t divfull, divEmpty ;
//sem_t outfull, outEmpty ;

char sumBuff [5][25] ;
char subBuff [5][25] ;
//char mulBuff [] ;
//char divBuff [] ;
//char outBuff [] ;

pthread_mutex_t sumMutex ;
pthread_mutex_t subMutex ;

void initData(){
        pthread_mutex_init(&sumMutex, NULL)      ;
        sem_init(&sumfull, 0, 0) ;
        sem_init(&sumEmpty, 0, BUFFER_SIZE) ;
        sem_init(&subfull, 0, 0) ;
        sem_init(&subEmpty, 0, BUFFER_SIZE) ;

        sumCounter = subCounter = mulCounter = divCounter = 0 ;
        sumFileEnd = subFileEnd = mulFileEnd = divFileEnd = 0 ;
}

void *plusReadThread(){
        printf("Enter to the plusReadThread\n");
        FILE *sumfp = fopen("sample.txt","r");
        char * line = NULL;
        size_t len = 0;
        ssize_t read;
        char *isSum ;
        int lineNumber = 1 ;
        if (lineNumber == 1){
                read = getline(&line, &len, sumfp) ;
                lineNumber ++ ;
        }
        while (!feof(sumfp)){
                printf("Enter to the while of plusReadThread\n");
                read = getline(&line, &len, sumfp) ;
                isSum = strchr(line, '+') ;
                if (isSum != NULL){
                        printf("Down on sumEmpty\n");
                        sem_wait(&sumEmpty);
                        pthread_mutex_lock(&sumMutex) ;
                        printf("Lock the mutex in plusReadThread\n");
                        if(sumCounter < BUFFER_SIZE){
                                printf("Counter was < 5 in plusReadThread\n");
                                char temp[20] ;
                                sprintf(temp, "%d", lineNumber);
                                strcat(temp, ".");
                                strcat (temp, line);
                                printf("lineNumber is %d line content is %s", lineNumber, line );
                                strcpy(sumBuff[sumCounter], temp);
                                printf("Copied the line in to the sumBuff\n");
                                printf("sumCounter = %d sumBuff[%d] = %s",sumCounter, sumCounter, sumBuff[sumCounter] );
                                sumCounter ++;
                                printf("sumCounter changed to %d\n", sumCounter);
                        }
                        pthread_mutex_unlock(&sumMutex);
                        printf("Unlock the mutex in plusReadThread\n");
                        sem_post(&sumfull);
                        printf("Signal on sumfull\n");
                }
                lineNumber ++;
        }
        if (feof(sumfp))
                sumFileEnd = 1;
        fclose(sumfp);
}
void *plusExec(){
        printf("Enter to the plusExec\n");
        char *search = "+" ;
        char *temp1;
        char *temp2;
        int operand1 ;
        int operand2 ;
        int result ;
        while (!sumFileEnd || sumCounter!=0){
                printf("Enter to the plusExec while\n");
                printf("Here sumCounter is %d \n", sumCounter);
                sem_wait(&sumfull);
                pthread_mutex_lock(&sumMutex);
                printf("Lock the mutex in plusExec\n");
                temp1 = strtok(sumBuff[sumCounter-1], search) ;
                operand2 = atoi(strtok(NULL, search));
                temp2 = strtok(temp1, ".") ;
                operand1 = atoi(strtok(NULL, ".")) ;
                result = operand1 + operand2 ;
                printf("%d %d\n", atoi(temp2) ,result);
                sumCounter --;
                sem_post(&sumEmpty);
                pthread_mutex_unlock(&sumMutex);
                printf("Unlock the mutex in plusReadThread\n");
        }
}

void *subReadThread(){
        printf("Enter to the subReadThread\n");
        FILE *subfp = fopen("sample.txt","r");
        char * line = NULL;
        size_t len = 0;
        ssize_t read;
        char *isSub ;
        int lineNumber = 1 ;
        if (lineNumber == 1){
                read = getline(&line, &len, subfp) ;
                lineNumber ++ ;
        }
        while (!feof(subfp)){
                printf("Enter to the while of subReadThread\n");
                read = getline(&line, &len, subfp) ;
                isSub = strchr(line, '-') ;
                if (isSub != NULL){
                        printf("Down on subEmpty\n");
                        sem_wait(&subEmpty);
                        pthread_mutex_lock(&subMutex) ;
                        printf("Lock the mutex in subReadThread\n");
                        if(subCounter < BUFFER_SIZE){
                                printf("Counter was < 5 in subReadThread\n");
                                char temp[20] ;
                                sprintf(temp, "%d", lineNumber);
                                strcat(temp, ".");
                                strcat (temp, line);
                                printf("lineNumber is %d line content is %s", lineNumber, line );
                                strcpy(subBuff[subCounter], temp);
                                printf("Copied the line in to the subBuff\n");
                                printf("subCounter = %d subBuff[%d] = %s",subCounter, subCounter, subBuff[subCounter] );
                                subCounter ++;
                                printf("subCounter changed to %d\n", subCounter);
                        }
                        pthread_mutex_unlock(&subMutex);
                        printf("Unlock the mutex in subReadThread\n");
                        sem_post(&subfull);
                        printf("Signal on subfull\n");
                }
                lineNumber ++;
        }
        if (feof(subfp))
                subFileEnd = 1;
        fclose(subfp);
}
void *subExec(){
        printf("Enter to the subExec\n");
        char *search = "-" ;
        char *temp1;
        char *temp2;
        int operand1 ;
        int operand2 ;
        int result ;
        while (!subFileEnd || subCounter!=0){
                printf("Enter to the subExec while\n");
                printf("Here subCounter is %d \n", subCounter);
                sem_wait(&subfull);
                pthread_mutex_lock(&subMutex);
                printf("Lock the mutex in subExec\n");
                temp1 = strtok(subBuff[subCounter-1], search) ;
                operand2 = atoi(strtok(NULL, search));
                temp2 = strtok(temp1, ".") ;
                operand1 = atoi(strtok(NULL, ".")) ;
                result = operand1 - operand2 ;
                printf("%d %d\n", atoi(temp2) ,result);
                subCounter --;
                sem_post(&subEmpty);
                pthread_mutex_unlock(&subMutex);
                printf("Unlock the mutex in subReadThread\n");
        }
}

int main (int argc, char* argv []){
        begin = clock();
        FILE *fp = fopen("sample.txt", "r") ;
        fscanf(fp, "%d", &numberOfLines) ;
        fclose(fp) ;

        initData() ;
        tid = (pthread_t*)malloc(4*sizeof(pthread_t)) ;
        pthread_create(&tid[0],NULL,plusReadThread,NULL);
        pthread_create(&tid[1],NULL,plusExec,NULL);
        pthread_create(&tid[2],NULL,subReadThread,NULL);
        pthread_create(&tid[3],NULL,subExec,NULL);

        pthread_join(tid[0] , NULL);
        pthread_join(tid[1] , NULL);
        pthread_join(tid[2] , NULL);
        pthread_join(tid[3] , NULL);

        end = clock();
        time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
        printf("%F\n", time_spent);
        exit(0);
}

Когда я запускаю sumReadThread (а также sumExec) отдельно, я не получаю никаких ошибок сегментации (тот же статус при использовании subReadThread и subExec). Но когда я использую их вместе, я получаю ошибку сегментации, и это трассировка стека, которая говорит, что это от atoi():

#0  0x00007ffff7834517 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff7830f60 in atoi () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x0000000000400f53 in plusExec () at cm.c:84
#3  0x00007ffff7bc4182 in start_thread ()
   from /lib/x86_64-linux-gnu/libpthread.so.0
#4  0x00007ffff78f147d in clone () from /lib/x86_64-linux-gnu/libc.so.6

person EmadSmart    schedule 17.06.2015    source источник
comment
Возможно, strtok возвращает NULL? atoi не любит, когда его вызывают с помощью NULL.   -  person lurker    schedule 18.06.2015
comment
@Tim3880 Tim3880 Я хочу разделить строку на 2 подстроки из определенного символа, и я узнаю об этом из: stackoverflow.com/questions/2523467/   -  person EmadSmart    schedule 18.06.2015
comment
пара temp1 = strtok(sumBuff[sumCounter-1], search) ; операнд2 = atoi(strtok(NULL, поиск)); если поиск равен +, разделите строку на 2 подстроки, в которых два операнда справа и слева от +   -  person EmadSmart    schedule 18.06.2015
comment
@ Tim3880 Tim3880, когда я просто запускаю код с одним из потоков (Sub или Sum), у atoi нет проблем   -  person EmadSmart    schedule 18.06.2015
comment
я не думаю, что strtok является потокобезопасным, и вы можете добавить проверку перед вызовами atoi, чтобы поймать неожиданные результаты. По крайней мере, вы можете избежать segfault. Функция strtok() использует статический буфер при синтаксическом анализе, поэтому она не является потокобезопасной. Используйте strtok_r(), если это важно для вас. проверьте linux.die.net/man/3/strtok_r   -  person Tim3880    schedule 18.06.2015
comment
Даже проверка перед вызовом atoi не исправляет, что strtok не является потокобезопасным   -  person M.M    schedule 18.06.2015
comment
atoi вызывает неопределенное поведение для некоторых входов; чтобы избежать этого, используйте strtol. (Хотя более вероятно, что ваша проблема здесь в strtok).   -  person M.M    schedule 18.06.2015
comment
read = getline(&line, &len, sumfp) ; isSum = strchr(line, '+') ; небезопасно. Не используйте line, проверяя ожидаемое значение read.   -  person chux - Reinstate Monica    schedule 18.06.2015
comment
Еще одна ошибка связана с использованием while (!feof(sumfp)), потому что EOF — это условие, которое устанавливается только после операции ввода-вывода, а не до. Этот цикл выполнится хотя бы один раз, даже если файл пустой.   -  person Jens    schedule 18.06.2015