我试图在“init_pointer”函数中初始化整数指针“p”。函数返回后,我打印指针和解除引用的值两次。第一个取消引用打印预期值100,但第二个取消引用打印随机值。
#include<stdio.h>
void init_pointer(int d, int **c){
(*c) = &d;
}
int main(){
int x = 100;
int *p;
init_pointer(x,&p);
printf("pointer = %p, value = %d\n",p,*p);
printf("pointer = %p, value = %d\n",p,*p);
return 0;
}
输出:
pointer = 0x7fffb4d4b9ac, value = 100
pointer = 0x7fffb4d4b9ac, value = 32567
答案 0 :(得分:9)
该函数已将值复制到init_pointer(int d, int **c)
d
位于init_pointer
的本地,由main
x
传递。 x
和d
都是单独的变量,其地址不同。访问d
之外init_pointer
的地址将导致Undefined Behavior。
调用这样的函数是没有意义的,但这样可行:
void init_pointer(int *d, int **c)
{
(*c) = d;
}
int main()
{
int x = 100;
int *p;
init_pointer(&x,&p);
printf("pointer = %p, value = %d\n",p,*p);
printf("pointer = %p, value = %d\n",p,*p);
return 0;
}
输出:
pointer = 0xbfde132c, value = 100
pointer = 0xbfde132c, value = 100
答案 1 :(得分:2)
void init_pointer(int d, int **c){
(*c) = &d;
}
此处*c
指向init_pointer()
内的本地副本。 init_pointer()
返回后,地址无效,p
中的main()
指向已释放的地址。
答案 2 :(得分:0)
在init_pointer中,您将参数d的地址分配给* c。参数的地址是堆栈地址。
在第一次调用printf时,堆栈(尽管已解除分配)仍然完好无损,因此p指向堆栈上丢弃的参数d,它仍然具有值100,并且* p首先被推入堆栈。
在第二次调用printf时,第一次调用已覆盖堆栈。虽然指针仍然指向同一个地址,但是它的值已被p的推动覆盖。因此打印p(地址)。
注意:使用&#34;堆栈(尽管已取消分配)&#34;我的意思是sp的堆栈(英特尔;向下增长)。此外,堆栈可以在任何时候被覆盖,例如,当中断发生时。