多线程挂掉----哪个大神可以解决下,多谢啦!

1 #include
2 #include
3 #include
4 #include
5 #define PAI 3.14159
6 void* area(void* arg){
7 double r = (double)arg;
8 double* s=malloc(sizeof(double));
9 s = PAI * r * r;
10 return s;
11 }
12 int main(void) {
13 printf("r=");
14 double r;
15 scanf("%lf", &r);
16 pthread_t tid;
17 int error=pthread_create(&tid, NULL, area, &r);
18 if(error){
19 errno=error;
20 printf("%m\n");
21 }else {
22 printf("pthread_create success\n");
23 }
24 #if 0
25 double
a;
26 pthread_join(tid, (void**)&a);
27 printf("s=%g\n", a);
28 free(a);
29 a=NULL;
30 #endif
31 #if 0
32 double
* a = (double**)malloc(sizeof(double));
33 pthread_join(tid, (void**)a);
34 printf("s=%g\n", (double)a);
35 free(*a);
36 a=NULL;
37 free(a);
38 a=NULL;
39 #endif
40 #if 0
40 #if 0
41 double
b=(double*)malloc(sizeof(double));
42 double** a=&b;
43 int error1=pthread_join(tid, (void**)a);
44 if(error1){
45 errno=error1;
46 printf("%m\n");
47 }
48 printf("s=%g\n", (double)a);
49 free(*a);
50 a=NULL;
51 free(b);
52 b=NULL;
53 #endif
54 #if 1
55 double
* a;
56 int error1=pthread_join(tid, (void**)a);
57 if(error1){
58 errno=error1;
59 printf("%m\n");
60 }
61 printf("s=%g\n", (double)a);
62 free(*a);
63 *a=NULL;
64 #endif
65 return 0;
66 }

执行结果 :

r=4
pthread_create success
段错误 (核心已转储)

gdb跟踪调试结果:

54 #if 1
55 double** a;
56 int error1=pthread_join(tid, (void**)a);
57 if(error1){
58 errno=error1;
59 printf("%m\n");
60 }
61 printf("s=%g\n", (double)a);
62 free(*a);
63 *a=NULL;
(gdb) l
64 #endif
65 return 0;
66 }
(gdb) b 54
Breakpoint 1 at 0x8048689: file ret.c, line 54.
(gdb) r
Starting program: /home/liushiwei/liushiwei/unix/14/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
r=3
[New Thread 0xb7dffb40 (LWP 7045)]
pthread_create success
[Thread 0xb7dffb40 (LWP 7045) exited]

Breakpoint 1, main () at ret.c:56
56 int error1=pthread_join(tid, (void**)a);
(gdb) p a
$1 = (double **) 0x8048709
(gdb) p *a
$2 = (double *) 0x18ebc381
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0xb7fb2e59 in pthread_join () from /lib/i386-linux-gnu/libpthread.so.0
(gdb) c
Continuing.

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)

注意:前面三个#if 0 到#endif 都可以执行成功,但最后一个#if 1 到#endif,段错误,请大神帮帮小弟,已经纠结几天了,不知道怎么解决。谢谢!

10个回答

一级指针也要捆绑存储区呀

JaryJary
JaryJary 从24行到30行,把24行的#if 0 改为#if 1,把54行的#if 1 改为 #if 0,你可以在试一试,程序没有错误,但一级指针,没有初始化。这就比如和我们声明一个FILE* fp;没有初始化,但在后面fp=fopen("/etc", "r");这里给它赋值,一样的道理。
大约 5 年之前 回复

double* a;
56 int error1=pthread_join(tid, (void**)a);

指针值为空...没有存储空间...

JaryJary
JaryJary 我代码抄错了,你看下我下面,重新整理过后的代码。
大约 5 年之前 回复

你这代码真够乱的,报段错误多为数组越界,指针使用错误,指针未分配存储空间,你好好看看你出问题的代码

JaryJary
JaryJary 我代码抄错了,你看下我下面重新整理过后的代码。
大约 5 年之前 回复

55 double* a
应该是这里的问题,下面代码运行之前没有给申请空间。
给个内存空间试试吧。

JaryJary
JaryJary 我代码抄错了,你看下我下面重新整理过后的代码。前三个#if 0 到对应的 #endif 之间,都可以执行成功,但最后一个#if 1 到 #endif 段错误!
大约 5 年之前 回复

ps:觉得你的代码中好多用法都没有见过,你是不是传说中的大神、高手?

JaryJary
JaryJary 我是个菜鸟,要不然早搞定了。
大约 5 年之前 回复

sorry,我没仔细看代码,抄错好多,下面是整理后的代码,不必看前三个#if 0到对应的#endif之间的代码 (这三段代码都是调试用的,不会执行),
只看最后一个 #if 1 到最后一个 #endif 之间的代码,为什么在第56行报段错误?
pthread_join()函数的第二个参数是线程过程函数的返回值的地址---输出参数。
就是说,我如果声明一个二级指针,如果我直接用malloc()分配堆内存,给它初始化,不会有问题,但如果不初始化,就不可以(一级指针不用初始化也行)。

1 #include
2 #include
3 #include
4 #include
5 #define PAI 3.14159
6 void* area(void* arg){
7 double r = (double)arg;
8 double* s=malloc(sizeof(double));
9 s = PAI * r * r;
10 return s;
11 }
12 int main(void) {
13 printf("r=");
14 double r;
15 scanf("%lf", &r);
16 pthread_t tid;
17 int error=pthread_create(&tid, NULL, area, &r);
18 if(error){
19 errno=error;
20 printf("%m\n");
21 }else {
22 printf("pthread_create success\n");
23 }
24 #if 0
25 double
a;
26 pthread_join(tid, (void**)&a);
27 printf("s=%g\n", a);
28 free(a);
29 a=NULL;
30 #endif
31 #if 0
32 double
* a = (double**)malloc(sizeof(double));
33 pthread_join(tid, (void**)a);
34 printf("s=%g\n", (double)a);
35 free(*a);
36 a=NULL;
37 free(a);
38 a=NULL;
39 #endif
40 #if 0
41 double
b=(double*)malloc(sizeof(double));
42 double** a=&b;
43 int error1=pthread_join(tid, (void**)a);
44 if(error1){
45 errno=error1;
46 printf("%m\n");
47 }
48 printf("s=%g\n", (double)a);
49 free(*a);
50 a=NULL;
51 free(b);
52 b=NULL;
53 #endif
54 #if 1
55 double
* a;
56 int error1=pthread_join(tid, (void**)a);
57 if(error1){
58 errno=error1;
59 printf("%m\n");
60 }
61 printf("s=%g\n", (double)a);
62 free(*a);
63 *a=NULL;
64 #endif
65 return 0;
66 }

GDB调试没有变化中,还是找走到第56行, 系统发SIGSEGV信号(段错误)。哪个大神,帮一下,谢谢!。

妹的!!!!!,重新整理过后的代码还是有错误,粘贴时,粘贴板会把** 粘贴成* ,再次重新整理一次,以下面的代码为准。

1 #include
2 #include
3 #include
4 #include
5 #define PAI 3.14159
6 void* area(void* arg){
7 double r = (double)arg;
8 double* s=malloc(sizeof(double));
9 s = PAI * r * r;
10 return s;
11 }
12 int main(void) {
13 printf("r=");
14 double r;
15 scanf("%lf", &r);
16 pthread_t tid;
17 int error=pthread_create(&tid, NULL, area, &r);
18 if(error){
19 errno=error;
20 printf("%m\n");
21 }else {
22 printf("pthread_create success\n");
23 }
24 #if 0
25 double
a;
26 pthread_join(tid, (void**)&a);
27 printf("s=%g\n", a);
28 free(a);
29 a=NULL;
30 #endif
31 #if 0
32 double
* a = (double**)malloc(sizeof(double));
33 pthread_join(tid, (void**)a);
34 printf("s=%g\n", (double)a);
35 free(*a);
36 a=NULL;
37 free(a);
38 a=NULL;
39 #endif
40 #if 0
41 double
b=(double*)malloc(sizeof(double));
42 double** a=&b;
43 int error1=pthread_join(tid, (void**)a);
44 if(error1){
45 errno=error1;
46 printf("%m\n");
47 }
48 printf("s=%g\n", (double)a);
49 free(*a);
50 a=NULL;
51 free(b);
52 b=NULL;
53 #endif
54 #if 1
55 double
* a;
56 int error1=pthread_join(tid, (void**)a);
57 if(error1){
58 errno=error1;
59 printf("%m\n");
60 }
61 printf("s=%g\n", (double)a);
62 free(*a);
63 *a=NULL;
64 #endif
65 return 0;
66 }

#include
#include
#include
#include
#define PAI 3.14159
void* area(void* arg){
double r = (double)arg;
double* s=malloc(sizeof(double));
s = PAI * r * r;
return s;
}
int main(void) {
printf("r=");
double r;
scanf("%lf", &r);
pthread_t tid;
int error=pthread_create(&tid, NULL, area, &r);
if(error){
errno=error;
printf("%m\n");
}else {
printf("pthread_create success\n");
}
#if 0
double
a;
pthread_join(tid, (void**)&a);
printf("s=%g\n", a);
free(a);
a=NULL;
#endif
#if 0
double
* a = (double**)malloc(sizeof(double));
pthread_join(tid, (void**)a);
printf("s=%g\n", (double)a);
free(*a);
a=NULL;
free(a);
a=NULL;
#endif
#if 0
double
b=(double*)malloc(sizeof(double));
double** a=&b;
int error1=pthread_join(tid, (void**)a);
if(error1){
errno=error1;
printf("%m\n");
}
printf("s=%g\n", (double)a);
free(*a);
a=NULL;
free(b);
b=NULL;
#endif
#if 1
double
* a;
int error1=pthread_join(tid, (void**)a);
if(error1){
errno=error1;
printf("%m\n");
}
printf("s=%g\n", (double)a);
free(*a);
*a=NULL;
#endif
return 0;
}

我再试一次 ,看行不行,粘贴板会不会把 ** 粘成 *.

pthread_join1
pthread_join2
pthread_join3

妹的!!!!!,上面两个代码粘贴时,粘贴板还是会把** 粘贴成* ,请以下面图片里的代码为准,pthread_join1(1行----31行);pthread_join2(31行----61行);pthread_join2(37行----67行)。谢谢。

。。。。。。。
。。。。。。。。。。
你先试一试,55行double** a ;之后申请个内存空间,然后再调用pthread_join()函数。
因为你声明了double** a 的指针,但并没有让它指向一个有效的内存空间,所以在调用pthread_join()函数是给你返回数据时发生错误。

你先试试吧。

JaryJary
JaryJary 陪了我 折磨久 虽然 暂时 我还没 搞清楚 以后  会搞清楚 的   C币给你了 。
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: 对啊,但我们提过接的条件呀。好了,我爱莫能助了。希望你能早点解决这个问题。搞明白记得发帖,我也学习学习。
大约 5 年之前 回复
JaryJary
JaryJary 线程过程函数,是我们定义,系统调用,是系统把线程过程函数的返回值放在和pthread_join()函数第二个参数捆绑的存储区里。
大约 5 年之前 回复
JaryJary
JaryJary 这个接,不是我们自己接的
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: int* p; int** pp = &p;这才对吧
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: 但是二级指针接不了啊。就相当于 int num;int** p = # 这说不通吧
大约 5 年之前 回复
JaryJary
JaryJary 我不是说了吗,写成一级指针,没有问题,我就是想用二级指针。
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: 不对不对,乱了。总之你把double** a 转换成一级的,再去获取估计就可以了
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: 试一下,在线等
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: 在56行处用(void*)a ,不用 (void**)a
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: 在56行处有(void*)a ,不用 (void**)a
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary:直接去获取就会失败。所以应该用*a去获取。你再试一试。
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: 按你说的我又看了下代码,确实会有些迷惑。我分析了一下,你看看对不对。一级指针直接和普通的数据变量存储区进行捆绑,而二级指针应该和一级指针进行捆绑,而这个程序中返回的s是一级指针,要想用二级指针捆绑他应对其取地址,然后才能被55行的二级指针捆绑。
大约 5 年之前 回复
JaryJary
JaryJary 因此,同样的道理,没初始化的二级指针,会和area的返回值进行捆绑,因此通过61行-----**a,就拿到了,存储在堆存储区的圆的面积。为什么不对?
大约 5 年之前 回复
JaryJary
JaryJary 却行的通,是因为,没初始化,这个一级指针是野指针,可以和任意存储区捆绑,但是pthread_join()函数,的第二个参数,会把线程过程函数--area返回值的地址赋值给pthread_join()函数的第二个参数,因此这时,pthread_join()函数的第二个参数就和area的返回值进行捆绑,因此通过27行-----*a,就拿到了,存储在堆存储区的圆的面积.
大约 5 年之前 回复
JaryJary
JaryJary 回复蚂蚁de臂膀: 是这样,先说一级指针,为什么没有初始化
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: 这么说能理解吗?
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: 而你的55行之后没有申请内存空间,不论你是几级指针都是一样的,都是存放地址数据的,想使用的话都需要捆绑一定大小的内存空间。
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: malloc就是从堆区中申请了相应大小的内存空间。所以你用double **a来接这个函数返回的地址,从而使用这块由malloc申请的内存空间。
大约 5 年之前 回复
csdnliming147
蚂蚁de臂膀 回复JaryJary: 如过申请指针变量,而不去捆绑内存,那么指针仅仅是一个大小为4byte的内存块,并且是用来存储地址数据的。需要的是将申请的指针绑定一块存储区才可以使用,才能想指针指向的内存区域写数据。
大约 5 年之前 回复
JaryJary
JaryJary 我就想知道,就用二级指针,不初始化,到底错在哪?(一级指针不初始化没有问题) 用gdb调试,或者其他方法,很明了的看出问题究竟是怎么回事?
大约 5 年之前 回复
JaryJary
JaryJary 32行(double** a = (double**)malloc(sizeof(double));),已经试过,如果分配堆内存初始化,不会有问题,
大约 5 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问