C语言pthread程序中的分段错误11

时间:2017-02-26 22:35:28

标签: c bash

这是我的代码,我几个小时都找不到bug。我在bash上运行它,它给出了正确的fibonacci输出,在行尾有分段错误11。但是当我使用Xcode运行它时,没有这样的分段错误,但最后返回0正常。

基本上我创建了一个运行函数calculate的pthread,在完成后,我在主线程中运行显示。

我感谢你的时间。

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

void *calculate(int n, int *arr)
{
    for (int i = 0; i <= n; i++)
    {
        if (i == 1)
            arr[i] = 1;
        else if (i > 1)
            arr[i] = arr[i - 1] + arr[i - 2];
    }
    return NULL;
}

void display(int n, const int *arr)
{
    for (int i = 0; i <= n; i++)
    {
        printf("%d ",arr[i]);
    }
}

int main(int argc, const char* argv[])
{
    if (argc != 2)
    {
        printf("Wrong argument. You need ONE positive number as argument.");
        return 1;
    }
    int number = atoi(argv[1]);
    if (number < 0)
    {
        printf("Plese enter a positive integer.");
        return 2;
    }
    else if (number == 0)
    {
        printf("0");
        return 0;
    }
    int *arr = (int*)malloc((number+1) * sizeof(int));
    arr[0] = 0;
    pthread_attr_t attr;
    pthread_t thread;
    pthread_attr_init(&attr);
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    pthread_create (&thread, &attr, calculate(number, arr), NULL);
    display(number, arr);
    free(arr);
    return 0;
}

2 个答案:

答案 0 :(得分:0)

请参阅以下pthread_create文档(http://man7.org/linux/man-pages/man3/pthread_create.3.html):

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

注意start_routine的参数放在'arg'参数中 - 一个不用参数直接调用函数:

  

pthread_create()函数在调用进程中启动一个新线程。新线程通过调用start_routine()开始执行; arg作为start_routine()的唯一参数传递。

作为最后一点,你应该在尝试查看它负责变异的任何内存之前加入线程(pthread_join):

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

答案 1 :(得分:0)

扩展松鼠的答案。您需要将实际函数传递给pthread_create,而不是在参数列表中调用它。否则,不仅在主线程中执行该函数,它的返回值也传递给pthread_create。该函数返回void*,因此不会导致编译错误。

您应该定义一个函数,该函数接受单个指针参数并返回void *并将其作为第3个参数传递。然后,为了传递参数,您可以定义一个可以保存所需值的结构,并将指针作为pthread_create的最终参数传递给它。

在你的线程函数中,你可以回转到正确的指针类型并读取值并在你的线程函数中使用它们。

这是一个完整的示例,展示如何包装多个参数并传递给pthread_create

我刚刚创建了一个结构来保存所需的参数并创建了一个传递给pthread_create的结构。在线程函数中,将其强制转换为实数类型并读取值。

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

struct params
{
    int n;
    int* arr;
};

void calculate(int n, int *arr)
{
    for (int i = 0; i <= n; i++)
    {
        if (i == 1)
            arr[i] = 1;
        else if (i > 1)
            arr[i] = arr[i - 1] + arr[i - 2];
    }
}

// wrapper to pass function to thread
void* calcwrap(void* data)
{
    struct params* p = (struct params*)data;
    calculate(p->n, p->arr);
    return NULL;
}

void display(int n, const int *arr)
{
    for (int i = 0; i <= n; i++)
    {
        printf("%d ",arr[i]);
    }
}

int main(int argc, const char* argv[])
{
    if (argc != 2)
    {
        printf("Wrong argument. You need ONE positive number as argument.");
        return 1;
    }
    int number = atoi(argv[1]);
    if (number < 0)
    {
        printf("Plese enter an integer.");
        return 2;
    }
    else if (number == 0)
    {
        printf("0");
        return 0;
    }
    int *arr = malloc((number+1) * sizeof(int));
    arr[0] = 0;

    struct params thread_params = {number, arr};
    pthread_attr_t attr;
    pthread_t thread;

    pthread_attr_init(&attr);

    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    pthread_create (&thread, &attr, calcwrap, &thread_params);
    pthread_join(thread, NULL);

    display(number, arr);
    free(arr);

    return 0;
}