gpt4 book ai didi

c - Pthread Posix 质因数分解得到奇怪的结果?

转载 作者:行者123 更新时间:2023-11-30 16:34:59 24 4
gpt4 key购买 nike

我有一个项目,我从命令行接收输入,例如“54 342 12”,并且应该为每个输入创建一个线程,并让线程返回一个整数数组,然后主线程应该打印出不同的质因数分解。但是我收到了奇怪的输出,例如一堆零。我不知道为什么,我们将不胜感激任何帮助。

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


typedef struct _thread_data_t {
int tid;
} thread_data_t;

void *runner(void *param);

int main(int argc, char *argv[]) {

pthread_t thr[argc];
pthread_attr_t attr;
int i, rc;
//int *primeFactor;
//primeFactor = (int *)malloc(sizeof(int)*argc);
//thread_data_t thr_data[argc];
printf("Prime Numbers: ");

//Get the default attributes
pthread_attr_init(&attr);
//creat the thread
for(i = 1; i < argc; ++i){
//thr_data[i].tid = i;
if ((rc = pthread_create(&thr[i],&attr,runner,argv[i]))){
fprintf(stderr, "error: pthread_create, rc: %d\n", rc);
return EXIT_FAILURE;
}
}

//Wait for the thread to exit
for(i = 1; i < argc; ++i){
void *returnValue;
int r = 0;
int x = (sizeof(returnValue) / sizeof(returnValue[0])) - 1;
pthread_join(thr[i], &returnValue);
for(r = 0; r < x; r++){
//int c = (int *)returnValue[r];
printf("%d ", ((int *)returnValue)[r]);
}
}
printf("\nComplete\n");

}

//The Thread will begin control in this function
void *runner(void *param) {
int *primeFactors;
int num = atoi(param);
primeFactors = (int *)malloc(sizeof(int)*num);
int i, j, isPrime;
int k = 0;
for(i=2; i<=num; i++)
{
if(num%i==0)
{
isPrime=1;
for(j=2; j<=i/2; j++)
{
if(i%j==0)
{
isPrime = 0;
break;
}
}

if(isPrime==1)
{
primeFactors[k] = i;
k++;
}
}
}


//Exit the thread
// pthread_exit(0);

// pthread_exit((void *)primeFactors);
pthread_exit(primeFactors);
}

最佳答案

这一行有问题:

int x = (sizeof(returnValue) / sizeof(returnValue[0])) - 1;

sizeof array/sizeof array[0] 仅适用于纯数组,不适用于指针。请注意,returnValue 是一个指针,因此 sizeof(returnValue) 确实如此不返回线程创建的整数序列的大小(以字节为单位),它给出指针需要在内存中存储的字节数。在x86_64 架构很可能是 8,所以在大多数情况下 x 是大于质因数的实际数量,您将访问指针超出范围,这就是您看到垃圾值的原因。

因为您要返回一个指向malloced位置的指针,所以您需要返回长度也是如此。最好的方法是创建一个结构返回值并将信息存储在那里。

创建一个结构体

struct thread_result
{
int *factors;
size_t len;
};

并返回指向该结构的指针,其中包含以下信息:

void *runner(void *param) {
int *primeFactors;
int num = atoi(param);
if(num == 0)
pthread_exit(NULL);

struct thread_result *res = calloc(1, sizeof *res);

res->factors = NULL;
res->len = 0;

int *tmp;

if(res == NULL)
pthread_exit(NULL);

int i, j, isPrime;
int k = 0;
for(i=2; i<=num; i++)
{
if(num%i==0)
{
isPrime=1;
for(j=2; j<=i/2; j++)
{
if(i%j==0)
{
isPrime = 0;
break;
}
}

if(isPrime==1)
{
tmp = realloc(res->factors, (k+1) * sizeof *res->factors);
if(tmp == NULL)
{
free(res->factors);
free(res);
pthread_exit(NULL);
}
res->factors = tmp;

res->factors[k++] = i;
res->len = k;
}
}
}


pthread_exit(res);
}

现在你可以获得这样的值:

for(i = 1; i < argc; ++i){
void *data;
pthread_join(thr[i], &data);

if(data == NULL)
continue; // error in thread

struct thread_result *res = data;

for(size_t r = 0; r < res->len; r++){
printf("%d ", res->factors[r]);
}

free(res->factors);
free(res);
}

并且不要忘记销毁线程属性

pthread_attr_destroy(&attr);

在离开main之前。但是您没有为线程设置任何属性,所以您可以使用以下命令创建线程:

pthread_create(&thr[i], NULL, runner, argv[i]);

还有don't cast malloc你必须检查返回值malloc

编辑

OP在评论中写道

I think I updated all of my code correctly to match what you said but now I am recieving the error "Segmentation dump (core dumped)" Any idea on why this might be?

其实没有,但你一定是错过了什么地方,因为当我编译并运行此代码:

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


typedef struct _thread_data_t {
int tid;
} thread_data_t;

void *runner(void *param);

struct thread_result
{
int *factors;
size_t len;
};

int main(int argc, char *argv[]) {

pthread_t thr[argc];
int i, rc;
printf("Prime Numbers:\n");

for(i = 1; i < argc; ++i){
if ((rc = pthread_create(&thr[i],NULL,runner,argv[i]))){
fprintf(stderr, "error: pthread_create, rc: %d\n", rc);
return EXIT_FAILURE;
}
}


for(i = 1; i < argc; ++i){
void *data;
pthread_join(thr[i], &data);

if(data == NULL)
continue; // error in thread

struct thread_result *res = data;

for(size_t r = 0; r < res->len; r++){
printf("%d ", res->factors[r]);
}

free(res->factors);
free(res);

puts("");
}


}

void *runner(void *param) {
int num = atoi(param);
if(num == 0)
pthread_exit(NULL);

struct thread_result *res = calloc(1, sizeof *res);

res->factors = NULL;
res->len = 0;

int *tmp;

if(res == NULL)
pthread_exit(NULL);

int i, j, isPrime;
int k = 0;
for(i=2; i<=num; i++)
{
if(num%i==0)
{
isPrime=1;
for(j=2; j<=i/2; j++)
{
if(i%j==0)
{
isPrime = 0;
break;
}
}

if(isPrime==1)
{
tmp = realloc(res->factors, (k+1) * sizeof *res->factors);
if(tmp == NULL)
{
free(res->factors);
free(res);
pthread_exit(NULL);
}
res->factors = tmp;

res->factors[k++] = i;
res->len = k;
}
}
}


pthread_exit(res);
}

我得到这个输出:

$ valgrind ./a 54 342 12
==17697== Memcheck, a memory error detector
==17697== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==17697== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==17697== Command: ./a 54 342 12
==17697==
Prime Numbers:
2 3
2 3 19
2 3
==17697==
==17697== HEAP SUMMARY:
==17697== in use at exit: 0 bytes in 0 blocks
==17697== total heap usage: 19 allocs, 19 frees, 3,640 bytes allocated
==17697==
==17697== All heap blocks were freed -- no leaks are possible
==17697==
==17697== For counts of detected and suppressed errors, rerun with: -v
==17697== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

这告诉我一切工作正常并且所有内存都已被释放好吧。

所以当你复制并粘贴我的代码时,你一定犯了一个错误回答。

关于c - Pthread Posix 质因数分解得到奇怪的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49103447/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com