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



所以前言,我是C的新手,所以请原谅我的程序有任何可怕的错误。

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

它将数字存储

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

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

然后假设线程对数字求和并将总和返回给主函数。

我遇到以下问题:

1.它并不总是发生,但有时我会在代码行之前出现分段错误,上面写着:

printf("Begining to create the thread");

2.我试图退还这笔款项的尝试没有奏效,经过几个小时的在线研究,我无法弄清楚原因。

3.编译程序时,出现以下错误:

gcc -g -o assn3 assn3.c -pthread
assn3.c: In function ‘AddUpNumbers’:
assn3.c:34:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  return (void*)total;
         ^
assn3.c: In function ‘main’:
assn3.c:96:3: warning: passing argument 1 of ‘pthread_join’ makes integer from pointer without a cast [enabled by default]
   pthread_join(&functionThread, &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);
            ^
assn3.c:97:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘void *’ [-Wformat=]
   printf("The total returned by the thread is %d", total);
   ^

这是我的代码:

#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("%dn", numberArray[i]);
                                    i = i + 1;
                    count = count + 1;
                } else {
                    break;
                }
            }
            numberArray[COUNT_LOCATION] = count;
            printf("Count Total: %dn", 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("%dn", numberArray[i]);
            i = i + 1;
            count = count + 1;
        }
        printf("See if error happens after this");
        numberArray[COUNT_LOCATION] = count;
        printf("Count Total: %dn", 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;
}

我的生成文件如下所示:

assn3: assn3.c
    gcc -g -o assn3 assn3.c -pthread

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

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

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);
        ^

您正在(创建并)传递指向pthread_t对象的指针作为pthread_join()的第一个参数,但与pthread_create()不同的是,pthread_join()希望您传递pthread_t本身,而不是指向它的指针。 各种形式的破坏(技术上是"未定义的行为")将接踵而至。

更新:此外,您传递给pthread_join()的第二个参数是指向void的未初始化指针。 如果pthread_create()试图在它指向的地方写任何东西,那么谁知道会发生什么(再次未定义的行为)。 您应该传递一个有效的指针,指向要写入结果的位置。 在这种情况下,那将是 &total .

pthread_create的语法是:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,  *(*start_routine) (void *), void *arg);

pthread_t - 是线程的 ID。因此,如果您有很多线程,请创建变量pthread_t id或值数组,例如pthread_t id[THREAD_NUM];然后你的函数将看起来像:
pthread_create(&id[i], NULL, &functionThread, (void*)numberArray);

With pthread_join(&functionThread, total); 

同样的事情。

int pthread_join(pthread_t thread, void **value_ptr);

所以你加入必须看起来像:

 pthread_join(&id[i], total);

最新更新