[英]Pthread Posix prime factorization getting weird results?
我有這個項目,我從命令行接收輸入,例如“ 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)
不會返回線程創建的int序列的大小(以字節為單位),它為您提供了指針需要存儲在內存中的字節數。 在x86_64架構上,最有可能是8,因此x
在大多數情況下將大於實際的質數,並且您將訪問指針超出范圍,這就是為什么看到垃圾值的原因。
因為你是返回一個指針malloc
ED的位置,你需要返回的長度為好。 最好的方法是為返回值創建一個結構並將信息存儲在那里。
創建一個結構
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]);
另外,不要強制轉換malloc
而必須檢查malloc
的返回值。
編輯
OP在評論中寫道
我認為我正確地更新了所有代碼,以符合您的要求,但是現在我收到錯誤消息“細分轉儲(核心轉儲)”,這可能是為什么嗎?
實際上沒有,但是您一定錯過了某些地方,因為當我編譯並運行以下代碼時:
#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)
告訴我,一切正常,所有內存也已釋放。
因此,當您從我的答案中復制並粘貼代碼時,您一定犯了一個錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.