我在这个代码中遇到了一个seg错误,但我在任何地方都找不到问题。它使用 -lpthread 编译得很好,但它就是无法运行。该程序从命令行接收一个整数,然后创建一个新线程来使用该值计算 collatz 猜想。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void print_con();
void calc_con(int *n);
int * values[1000];
int main(int argc, char * argv[])
{
int* num;
*num = 15;
pthread_t thread;
pthread_create(&thread,(pthread_attr_t*)NULL, (void *)&calc_con, (void *)num);
pthread_join(thread, NULL);
print_con();
return 0;
}
void calc_con(int *n)
{
int i = 0;
int * x;
*x = *n;
*values[0] = *x;
while(*x > 1)
{
if(*x % 2 == 0)
*x /= 2;
else if(*x % 2 == 1)
{
*x *= 3;
*x++;
}
i++;
*values[i] = *x;
}
pthread_exit(0);
}
void print_con()
{
int i;
for(i = 0; i < 1000; i++)
{
if(*values[i] > 0)
printf("%d", *values[i]);
}
}
你需要传递一个void *
作为参数来pthread_create
,但你仍然需要尊重基础知识:
int* num;
*num = 15;
pthread_t thread;
pthread_create(&thread,(pthread_attr_t*)NULL, (void *)&calc_con, (void *)num);
在这里*num = 15;
您正在将15
写入未初始化的指针。这是未定义的行为。
我会做的:
int num = 15;
pthread_t thread;
pthread_create(&thread,(pthread_attr_t*)NULL, &calc_con, &num);
请注意,您不必从非 void 上的指针强制转换为void *
。由于num
是在main
例程中声明的,因此您可以安全地将指针传递给线程。
请注意,正如Dasblinkenlight所指出的,您还必须在calc_con
中修复接收端,它具有相同的问题:
int * x; // uninitialized pointer
*x = *n; // copy data "in the woods"
只需取消对局部变量的引用,您就有了您的值:
int x = *((int *)n);
另一个:
int * values[1000];
是一个未初始化的整数指针数组,而不是您想要的整数数组。它应该是
int values[1000];
然后
values[0] = x;
(不是因为有很多*
运算符,所以它是好代码)
您正在使用 void*
将int
传递给线程。这将适用于许多平台,但不能保证该数字会正确"往返"。获取指针后,将其保存在取消引用的未初始化指针中,这是不正确的。
改为将指针传递给num
,并将指针直接复制到x
:
void calc_con(void *n);
...
void calc_con(void *n) {
int i = 0;
int * x = n;
*values[0] = *x;
while(*x > 1) {
if(*x % 2 == 0) {
*x /= 2;
} else if(*x % 2 == 1) {
*x *= 3;
*x++;
}
i++;
*values[i] = *x;
}
pthread_exit(0);
}
...
int num = 15;
pthread_create(&thread,(pthread_attr_t*)NULL, calc_con, (void *)&num);