指针作为函数参数?

时间:2014-10-22 07:42:14

标签: c pointers

代码输出 11,11,未定义值 .......请解释一下?

#include <stdio.h>

void f(int **const p); 

int main() 
{ 
   int i = 10; 
   int *p = &i; 
   f(&p); 
   printf("%d ", *p); 
   printf("%d ", *p); 
} 

void f(int **const p) 
{ 
   int j = 11; 
   *p = &j; 
   printf("%d ", **p); 
}

4 个答案:

答案 0 :(得分:8)

它是undefined behavior,因为你设置*p指向一个局部变量,一旦函数退出所有局部变量超出了范围,这会给你一个悬空指针。


真正发生的事情是,以前的函数调用会重用以前由局部变量j占用的内存,因此您将打印函数设置该内存的任何值。 / p>

答案 1 :(得分:6)

下面:

   *p = &j; 

j的范围小于p的范围。函数f返回时,p中存储的值不再有效。因此未定义的行为。

答案 2 :(得分:1)

变量的范围是定义它的函数的局部。在你的情况下,j是函数f的局部变量。变量j在函数f之外不再可见。因此p变为悬空指针。如果你期望输出为11 11 11然后你必须将j声明为静态变量。

答案 3 :(得分:1)

一旦退出函数f(),变量j就会超出范围,但指针p 仍然指向该内存地址。这是未定义的行为。

简化的代码内联版本,评论发生了什么:

int main() 
{ 
  int *p;             //create pointer
  { 
    int j = 11;       //create j in local scope
    p = &j;           //set p to point at j (refered to as address A from now)
    printf("%d ", *p);//print value at A  "11 "
  }                   //j goes out of scope
  printf("%d ", *p);  /*print value at A  "11 11 "  
                       ***UB: as memory at A is not used to store j any more,
                       printf() can use it to store variables for its own use*/
  printf("%d ", *p);   /*print value at A  "11 11 GARBAGE"  
                        ***UB: as memory at A is not used to store j any more,
                        the previous printf() call touched A at some point
                        changing the contents (and thus the read value)*/
}

说实话,我很惊讶第一个printf()的调用在输出之前没有破坏内存。

您不能依赖第二个printf输出'正确的值'。即使在这个简单的例子中,所看到的行为仅由实现决定,而不同的编译器很可能会以不同的方式处理它。 只是通过更改代码,非常可能输出会发生变化,例如,在printf可能覆盖内存并停止输出正确之前声明一个新变量。

相关问题