как вернуть массив из pthread - PullRequest
       7

как вернуть массив из pthread

0 голосов
/ 27 сентября 2018

Я пытался получить массив целых из потока.Я думаю, что я действительно близко.Ошибки, которые я получаю, связаны с разыменованием указателя void и недопустимым использованием выражения void здесь

assn3.c: 29: 29: error: разыменование указателя 'void *' [-Werror]

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

assn3.c: 29: 18: ошибка: недопустимое использование пустого выражения

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 голосов
/ 28 сентября 2018

Здесь есть несколько неправильных вещей:

  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

0 голосов
/ 01 октября 2018

Есть несколько вещей, которые необходимо исправить, как указано ранее.

Как указано, не используйте локальную переменную в качестве адреса возврата.Он не будет доступен, когда поток вернется.Лучше использовать глобальную переменную и динамически распределять память.Вы можете освободить его в функции, которая создала поток.

Для доступа к переменным, которые изменяются потоком, вы можете передать его функции потока, используя четвертый аргумент в 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;
    }
0 голосов
/ 28 сентября 2018
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 с, только что он должен сначала получить значение, чем приведен к инт.Вы хотите это:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...