C pthread程序中出现意外的分段错误

C pthread程序中出现意外的分段错误,c,C,引言,我是C语言的新手,请原谅我的程序所犯的可怕错误 我正在尝试编写一个程序,该程序将接受作为程序参数传入的数字列表或包含在传入路径的文件中的数字列表 它将数字存储到数组中,并将有多少数字存储到数组的第一个元素中。它最多只能存储100个数字 然后它创建一个pthread并将指向数组的指针传递给线程 然后,假设线程将这些数字相加,并将总和返回给主函数 我遇到以下问题: 一,。这种情况并不总是发生,但有时我会在代码行前面出现一个分段错误,它会说: 二,。我试图退还这笔钱的尝试不起作用,经过数小时的在

引言,我是C语言的新手,请原谅我的程序所犯的可怕错误

我正在尝试编写一个程序,该程序将接受作为程序参数传入的数字列表或包含在传入路径的文件中的数字列表

它将数字存储到数组中,并将有多少数字存储到数组的第一个元素中。它最多只能存储100个数字

然后它创建一个pthread并将指向数组的指针传递给线程

然后,假设线程将这些数字相加,并将总和返回给主函数

我遇到以下问题:

一,。这种情况并不总是发生,但有时我会在代码行前面出现一个分段错误,它会说:

二,。我试图退还这笔钱的尝试不起作用,经过数小时的在线调查,我不知道为什么

三,。当我编译程序时,会出现以下错误:

这是我的密码:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define NO_ARGS 1
#define ONLY_SINGLE_ARG 2
#define PATH_TO_READ_FROM 1
#define MAX_NUMBERS 101
#define MAX_CHAR_INPUT 255
#define COUNT_LOCATION 0

void* AddUpNumbers(void* arrayPointer) {
    printf("Created the pthread!");
    int* numbersArray = (int*)arrayPointer;
    int count = numbersArray[COUNT_LOCATION];
        int total = 0;

        int i = 1;
        while (i < count) {
                total = total + numbersArray[i];
        }
    printf("The total to be returned is %d", total);
    return (void*)total;
}

int main(int argc, char* argv[]) {
    FILE * numbersFile = NULL;
    int count = 0;
    int numberArray[MAX_NUMBERS];
    //Initialize the Array
    int i = 0;
    while (i < MAX_NUMBERS) {
        numberArray[i] = 0;
        i = i + 1;
    }

    if (argc == NO_ARGS) {
        printf("Usage: # or file path, #, #, ..., #\n");
    } else if (argc == ONLY_SINGLE_ARG) {
        numbersFile = fopen(argv[PATH_TO_READ_FROM], "r");
        if (numbersFile != NULL) {
            char buff[MAX_CHAR_INPUT];
            i = 1;
            count = 0;
            while (i < MAX_NUMBERS) {
                if (fscanf(numbersFile, "%s", buff) != EOF) {
                    numberArray[i] = atoi(buff);
                    printf("%d\n", numberArray[i]);
                                    i = i + 1;
                    count = count + 1;
                } else {
                    break;
                }
            }
            numberArray[COUNT_LOCATION] = count;
            printf("Count Total: %d\n", numberArray[COUNT_LOCATION]);
        } else {
                       printf("Error: Could not open file!\n");
                        return -1;
        }
    } else if (argc < MAX_NUMBERS + 1) {
        i = 1;
        count = 0;
        while (i < argc) {
            numberArray[i] = atoi(argv[i]);
            printf("%d\n", numberArray[i]);
            i = i + 1;
            count = count + 1;
        }
        printf("See if error happens after this");
        numberArray[COUNT_LOCATION] = count;
        printf("Count Total: %d\n", numberArray[COUNT_LOCATION]);
    } else {
                printf("Too many numbers! This program can only add up to: %d numbers.\n", MAX_NUMBERS);
                return -1;
    }
    printf("Begining to create the thread");
    pthread_t functionThread;
    int creationSuccess = 0;

    void* total;

    creationSuccess = pthread_create(&functionThread, NULL, AddUpNumbers, (void*)numberArray);
    if (creationSuccess == 0) {
        pthread_join(&functionThread, total);
        printf("The total returned by the thread is %d", *((int)total));
    } else {
        printf("Something went wrong.\n");
    }
    if (numbersFile != NULL) {
        fclose(numbersFile);
    }
    return 0;
}

pthread\u create
的语法是:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,  *(*start_routine) (void *), void *arg);
pthread_t-是线程的id。因此,创建变量
pthread\u t id
,或者如果有很多线程,那么创建一个值数组,比如
pthread\u t id[THREAD\u NUM]
然后,您的func将如下所示:
pthread_创建(&id[i],NULL,&functionThread,(void*)numberArray)

同样的事情

int pthread_join(pthread_t thread, void **value_ptr);
因此,您必须看起来像:

 pthread_join(&id[i], total);

您应该非常小心编译器警告。要么把它们清理干净,要么很好地理解它们为什么没问题。请特别注意有关数据类型不匹配的警告

在这种情况下,此警告可能解释了主要问题:

您正在(创建并)传递一个指向
pthread\u t
对象的指针,作为
pthread\u join()
的第一个参数,但与
pthread\u create()
不同,
pthread\u join()
希望您传递的是
pthread\u t
本身,而不是指向它的指针。一切形式的破坏(技术上称为“未定义的行为”)都将接踵而至


UPDATE:此外,传递给
pthread\u join()
的第二个参数是指向
void
的未初始化指针。如果
pthread\u create()
尝试在它指向的位置写入任何内容,那么谁知道会发生什么(再次出现未定义的行为)。您需要传递一个有效指针,指向要写入结果的位置。在这种情况下,这将是
&total

错误可能不会发生在您认为的地方。标准输出通常是行缓冲的。调用的
printf()
调用的输出不包含任何换行符,因此它将被缓冲,而不是立即写入。这是一个好消息。
functionThread
确实是
pthread\t
类型的变量。它在调用
pthread\u create()
之前声明了几行。此外,您的示例
pthread\u join()
调用不正确。事实上,这与OP的错误完全相同。将它与你发布的原型进行比较。对不起,这是真的。出于某种原因,我认为
functionThread
-本身就是一个函数声明。但仍然必须在pthread_create中使用
&
调用func<代码>pthread_创建(&functionThread,NULL,&AddUpNumbers,(void*)numberraray)谢谢你的帮助!这很有道理!唉,我觉得自己像个白痴,因为我没抓住那个。非常感谢你!我看到了您的更新,并实施了修复。谢谢你的帮助!
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,  *(*start_routine) (void *), void *arg);
With pthread_join(&functionThread, total); 
int pthread_join(pthread_t thread, void **value_ptr);
 pthread_join(&id[i], total);
In file included from assn3.c:12:0:
/usr/include/pthread.h:261:12: note: expected ‘pthread_t’ but argument is of type ‘pthread_t *’
 extern int pthread_join (pthread_t __th, void **__thread_return);
        ^