我一直在尝试从线程中获取一个整数数组。我想我真的很亲近。我遇到的错误是关于取消引用空指针和此处无效使用空表达式
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);
}
答案 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)
这里有几处错误:
for(int j = 0; j < sizeof(answer); j++)
//这将不告诉您数组中的#/元素
pthread_join()
可能不是传回整数缓冲区的最佳方法
当然,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;
}