最近自己写了一个链表。其中涉及到 create search delete操作,
让自己重新认识到char* char**到底有什么异同.
int add_account_list(ACCOUNT_LIST** first, ACCOUNT_LIST** last, int *account)
{
ACCOUNT_LIST* curr_node=NULL;
if((*first) == NULL)
{
curr_node=(ACCOUNT_LIST*)malloc(sizeof(ACCOUNT_LIST));
if(curr_node == NULL)
{
return FAILURE;
}
*first=curr_node;
curr_node->account=(*account);
curr_node->next=NULL;
*last =*first;
}
else
{
curr_node=(ACCOUNT_LIST*)malloc(sizeof(ACCOUNT_LIST));
if(curr_node == NULL)
{
return FAILURE;
}
curr_node->account=(*account);
curr_node->next=NULL;
(*last)->next=curr_node;
*last=curr_node;
}
return SUCCESS;
}
这是最终的实现, 之前没有注意
用的都是 类似int add_account_list(ACCOUNT_LIST* first, ACCOUNT_LIST* last, int *account)
这样的接口
发现每次 都没有成功 后来gdb了一把发现内都是初始化好了 赋值好了 但一返回就不行了 还是null.
那么我们就得来看一下 一个最基本的问题了 也是 很多面试中遇到的:
111 int mall_int(int **p)112 {
113 *p=(int*)malloc(sizeof(int));
114 return 0;
115 }
116 int mall_2(int *p)
117 {
118 p=(int*)malloc(sizeof(int));
119 return 0;
120 }
这两个mall_*函数到底做了什么?
在main 中调用 这两个函数
124
125 int *p=NULL;
126 //p=(int*)malloc(sizeof(int));
127 mall_2(p);
128 //mall_int(&p);
129 *p=34;
130 mall_int(&p);
131 *p=64;
一run 就会coredump. gdb一查看。
在进入mall_2前
(gdb) p p
$1 = (int *) 0x0
(gdb) p &p
$2 = (int **) 0x7fffffffda38
进入了 mall_2后
(gdb) p p
$3 = (int *) 0x0
(gdb) p &p
$4 = (int **) 0x7fffffffda18
可见 函数传递指针也是传的指什的值 即NULL, (int *) 0x0, 指针已经 是另外的一个 也就是**18 这个指针。 我们的本意思是想给*38这个地址 malloc一个空间 可是事与愿违, 那们我们怎么样达到我们想要的目的,把*38传进去呢? 那么答案 就是传地址 把地址的值传过去,给这个地址分配一个空间 那么函数原型就变成了 int mall_int(int **p) ,调用的时候就成了 mall_int(&p)
gdb 看一下 调用mall_int的过程
进入mall_int前
(gdb) p p
$1 = (int *) 0x0
(gdb) p &p
$2 = (int **) 0x7fffffffda38
进入后
(gdb) p p
$3 = (int **) 0x7fffffffda38
(gdb) p &p
$4 = (int ***) 0x7fffffffda18
(gdb) p *p
$7 = (int *) 0x603010
可以看出 p的地址变了 但他的值变成了我们外面的p的地址 下一步我们就要给38 malloc一个空间 这时就要对它解引用, *P=(int*)malloc(sizeof(int))
以上是我的个人理解, 后面我找点别人理论上的支持,我印象中记得有个文章说的不错。
这里面有两个东西 1) char** 怎样用, 2) 函数的传值 传指针是怎么回事,