探讨pthread_join()函数第二个形参为啥是二级指针问题


前段时间在看linux编程,看到join函数,看这个函数的形参觉得很奇怪,为啥是个二级指针,不就是想给一个指针赋值,至于弄得这样高深嘛?

int pthread_join(pthread_t thread, void **retval);

先看一个简单的例子:

例子1:

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

#define N 64

int a = 10;
void * handler(void *arg)
{
	printf("a=%d, %s\n", a, (char *)arg); 
	strcat((char *)arg, " ......");
	pthread_exit(arg); 
}
	
int main()
{
	pthread_t tid;
	char buf[N] = {"welcome"};
	void *result;
	
	if (pthread_create(&tid, NULL, handler, (void *)buf) != 0)
		exit(-1);
	printf("*\n");
	pthread_join(tid, &result);
	printf("ret:%s\n", (char *)result);
	
	return 0;
}
其实就是想给result这个指针赋值,那为啥形参不是
pthread_join(tid, result);

pthread_join函数的源码我没有找到,所以原因我也不得而知了,觉得心塞,大概是因为自己的无知吧~

直到今天我写一个项目的时候,遇到一个问题,如何将一级指针传递到函数里去,然后修改这个指针的值,可无论我怎么修改都改变不了,甚至程序还崩溃了!

例子2:

#include <stdio.h>

int array[4]={1,2,3,4};

void test(int *t)
{
	t=0x114455;
}

int main()
{
	
	int *p=array;
	printf("p=0x%X\n",p);
	test(p);
	printf("p=0x%X\n",p);
	
	printf("%x %d %d %d\n",array[0],array[1],array[2],array[3]);
}


看这个程序,我想在test()函数里修改指针p的地址,而不是想修改p所指内容的值.

test()函数里那个t我怎么写都很难写出正确的代码,反正就是感觉怎么写都改变不了函数外面p的值;

怎样写才正确呢,才能达到我想要的目的?

例子3:

#include <stdio.h>

int array[4]={1,2,3,4};

void test(int **t)
{
	*t=0x114455;
}

int main()
{
	
	int *p=array;
	printf("p=0x%X\n",p);
	test(&p);
	printf("p=0x%X\n",p);
	
	printf("%x %d %d %d\n",array[0],array[1],array[2],array[3]);
}

看到没有,这个函数经过这样改动就可以达到在函数内部修改函数外部的指针了,为什么这样就可以呢?

下面来分析下指针这个东西,指针其实就是一块内存,32位系统里,指针其实就是一个4字节的变量,只不过我们人为的规定他的值是指针而不是变量;


int *p=0x1234;意思就是p这个int类型的指针指向0x1234这个地址,由于p本身也是占用内存的,那它肯定也是有地址的,假设它的地址是0x4001020;

c语言中如果想打印出来指针p的地址值,只需要执行printf("p的地址是0x%X\n",p); 即可.

我们看下例子2中,

void test(int *t)
{
	t=0x114455;
}
这个函数的形参,我们传递进来的是0x1234这块内存,若在test函数里执行*t=1;那么之前的值0x55667788就变成值1了;

延伸下:那如果我们执行t++,又是什么样子的呢,经过我的实验,test执行完毕后p的值还是0x1234,丝毫没有改变啊! 这个是为什么呢?请大家自己思考这个问题?

我们照葫芦画瓢,test形参是*t的时候我们操作的是p所指向那块内存的值,那如果我们传递**p,是不是就可以操作0x4001020变量的值了,

这个时候执行*t=0x114455,等test函数执行完毕后,然后打印出p的值我们就会发现p的值真的改了.

我说的这么啰嗦不知大家是否明白了.

总结下:例子2传递的是一级指针,他只能修改p所指向那个内存的值,例子3所传递的就是指针p内存的地址,所以修改它就是修改了它自己的指向;

现在我们回过头了再看看例子1就知道了作者的意图就是想在thread_join里改变main函数里result变量的值,仅此而已~

猜你喜欢

转载自blog.csdn.net/yunjie167/article/details/79181333