首页 > 解决方案 > 给指针赋值会出错

问题描述

请告诉我这段代码有什么问题,我无法打印出现分段错误错误的值。

int main()
{
  int i=3, *p;
  p = &i+1;
  *p = 30;
  printf(“%d”, *p);
 } 

如果我使用此代码,它工作正常。

int main()
    {
      int i=3, *p, *q;
      q = &i;
      p = q+1;
      *p = 30;
      printf(“%d”, *p);
     } 

感谢您的回复

标签: cclang

解决方案


@Olaf Dietsche 有一个非常好的答案,但是由于您用给定的代码提出了这个问题,我假设您不太了解指针和&运算符的基础知识。

让我从你的例子开始,你有一个“int”变量和一个指向它的指针:

int a = 10;
int* p = &a;

这段代码所做的是声明一个局部变量 type int,然后声明另一个 type 变量int*。然后用a使用&操作符的地址初始化指针。

您现在必须了解每个变量都存储在其地址并具有一定的价值。这意味着变量var存储在地址中&var,并且具有存储在地址位中的值&var。这适用于所有变量,包括指针!

在上面的示例中,变量a存储在地址处&a,值为 10。指针p存储在地址处&p,值为&a

如果你打算使用这样的指针,你必须了解局部变量的作用域和生命周期。例如,在下面的函数中,var是一个局部变量。它仅在函数执行时才在堆栈上分配,然后弹出。

void f()
{
    int var = 10;
    var = var + 5;
} // <-- scope of the function is exited. var is popped from the stack.

您可以使用指针来保存局部变量的地址。但是,您需要注意,如果退出范围,则其中定义的变量不存在记录器。任何保存这些变量地址的指针都不会改变它们的值,但会指向用于其他用途的地址。例如:

int main()
{
    int* p;

    // now we create a scope
    {
        int a = 10;
        p = &a;
    }

    // this is undefined behaviour.
    printf("%d", *p);

    return 0;
}

即使代码将编译和运行而不会出错,但它是不正确的。如果你运行它,没有任何东西可以保证输出是什么,因为a当作用域退出时,地址已经被释放,并将用于在堆栈上存储其他东西。

为什么你的第一个例子会崩溃?@Olaf Dietsche 在他的回答中解释了这一点。

为什么你的第二个例子没有崩溃?这与我的上一个示例类似。它会编译并运行,但你不能保证会发生什么。


推荐阅读