如何从pthread返回数组

时间:2018-09-27 17:29:28

标签: c pthreads

我一直在尝试从线程中获取一个整数数组。我想我真的很亲近。我遇到的错误是关于取消引用空指针和此处无效使用空表达式

assn3.c:29:29:错误:取消引用“ void *”指针[-Werror]

printf(" %d", (int)answer[j]);
                         ^

assn3.c:29:18:错误:无效使用void表达式

printf(" %d", (int)answer[j]);

我尝试将函数的返回类型更改为int *,但似乎并不喜欢。我在这里想念什么?

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

void *getFactors(void *param);

int main(int argc, char *argv[])
{
    for(int i = argc; i > 0; i--)
    {
            void *answer;
            pthread_t tid;
            pthread_attr_t attr;
            if (atoi(argv[i])<0)
            {
                    fprintf(stderr, "%d must be > 0\n", atoi(argv[i]));
                    return -1;
            }

            pthread_attr_init(&attr);
            pthread_create(&tid, &attr, getFactors, argv[i]);
            pthread_join(tid, &answer);

            printf("%d", atoi(argv[i]));
            printf(":");

            for(int j = 0; j < sizeof(answer); j++)
            {
                    printf(" %d", (int)answer[j]);
            }
            printf("\n");
    }
}

还有线程功能

void *getFactors(void *param)
{
    int a[10];
    int n = atoi(param);

    int i = 0;
    while (n%2 == 0)
    {
            a[i] = 2;
            n/=2;
            i++;
    }
    int f=3;
    while (f * f <= n)
    {
            if (n % f == 0)
            {
                    a[i]=f;
                    n /= f;
                    i++;
            }
            else
            {
                    f += 2;
            }
    }
    if (n<1)
    {
            a[i]=n;
            i++;
    }

    int* buffer = (int*) malloc(i);
    buffer = a;
    return (void *) buffer;

    pthread_exit(0);
}

3 个答案:

答案 0 :(得分:2)

void *answer;
...
int * answer_beeing_an_int_arr = answer;
printf(" %d", answer_beeing_an_int_arr[j]);

这就是您想要的。但是您会发现:

printf(" %d", (int)answer[j]); 

不起作用。你为什么问?这是因为强制转换(int)的优先级比数组下标[j]的优先级低,而且您也不会告诉编译器answer是指向int的指针,只是它应该首先获取值,而不是强制转换为int。您想要这个:

printf(" %d", ((int*)answer)[j]); 

您想告诉编译器,答案是指向int的指针。然后,您要添加该指针sizeof(int) * j字节并取消引用。

记住要free(answer)

现在输入您的代码:

buffer = a;

是错误的。它将指针分配给另一个指针。您要复制指针后面的值,而不是指针本身。您需要:

memcpy(buffer, a, sizeof(int) * i);

for (size_t j = 0; j < i; ++j) {
    buffer[j] = a[j];
}

复制数组值。

... = malloc(i);

这将分配i个字节。您可能会注意到,int没有1字节(CHAR_BIT位,可能为8)。它有更多。可以是2,可以是更多。 sizeof(int)会告诉您int有多少字节。因此必须是:

int *buffer = malloc(i * sizeof(int));

或如我所愿:

int *buffer = malloc(i * sizeof(*buffer));

也:

int* buffer = (int*) malloc(i);
...
return (void *) buffer;

无需强制指向void*void*的指针。 void*是一个通用指针,它是什么都没有的指针。只是:

int* buffer = malloc(i * sizeof(*buffer));
...
return buffer;

答案 1 :(得分:1)

这里有几处错误:

  1. for(int j = 0; j < sizeof(answer); j++) //这将告诉您数组中的#/元素

  2. pthread_join()可能不是传回整数缓冲区的最佳方法

  3. 当然,printf(" %d", (int)answer[j]);是编译错误:(

建议:

通读本教程,并相应地重组代码:

http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

或者您可以浏览以下内容:

http://www.cs.kent.edu/~ruttan/sysprog/lectures/multi-thread/multi-thread.html

答案 2 :(得分:0)

如前所述,您需要纠正一些事情。

如前所述,请勿将局部变量用作返回地址。线程返回时将无法访问。最好使用全局变量并动态分配内存。您可以在创建线程的函数中释放它。

要访问由线程更改的变量,可以使用pthread_create(3)中的第四个参数将其传递给线程函数,然后再访问它。或使用pthread_join作为返回值访问它。

如果多个线程正在访问该变量,则可能需要使用互斥锁或其他同步原语。

下面给出了一个使用pthread_join(3)返回数组的简单示例。

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

    #define ARRAY_LEN 10
    void *functionPthread(void *);

    int *retArray;

    int main()
    {
            int rc, i;
            pthread_t th;
            retArray = (int*) malloc(sizeof(int) *ARRAY_LEN);

            if(rc = pthread_create(&th, NULL, &functionPthread, NULL))
            {
                    printf("Thread creation failed, return code %d, errno %d", rc, errno);
            }

            pthread_join(th, (void**)&retArray);

            for(i = 0; i < ARRAY_LEN; i++)
                    printf("%d ", retArray[i]);
            printf("\n");
            free(retArray);
            return 0;
    }

    void *functionPthread(void *)
    {
            int i;
            for(i = 0; i < ARRAY_LEN; i++)
                    retArray[i] = i;
            return retArray;
    }