-2
#include <stdio.h>

int *sum_returning_pointer(int *x, int *y)
{
    // Call be reference
    int z = (*x) + (*y);
    return &z;
}

void main(int *argc, char *argv[])
{
    int a = 1, b = 2;
    int *p = sum_returning_pointer(&a, &b);
    printf("Sum = %d\n", *p);
}

使用上面的函数,我试图将作为对被调用函数的引用传递的两个数字相加,并返回指向存储总和的变量的指针。但我说奇怪的错误。

Error has occured.
Segmentation Fault.

这个错误是什么意思?我该如何解决?为什么会出现这个错误?

4

2 回答 2

0

问题不在于如何取消引用,而在于如何确保指针有效。在您的代码中,将返回局部变量的地址。当程序从函数返回时,此变量的生命周期结束。之后取消引用此指针会调用Undefined Behavior

请注意,通常像这样的小对象int应该按值返回。

从函数返回指向结果的指针有 3 种通用策略。

  1. (IMO,最好的)让调用者处理生命周期。
int *foo(const int *x, const int *y, int *z) {
  *z = *x + *y;
  return z;
}

用法:

int x = 1, y = 2, z;
int *res = foo(&x, &y, &z);
  1. 使用动态存储
int *foo(const int *x, const int *y) {
  int *z = malloc(sizeof *z);
  if (!z) {
    // complain
    return NULL;
  }
  *z = *x + *y;
  return z;
}

此解决方案往往非常缓慢且容易出错,因为调用者负责释放结果。

  1. 使用静态。
int *foo(const int *x, const int *y) {
  static int z;
  z = *x + *y;
  return &z;
}

效果很好,因为静态变量的生命周期延长了程序的整个执行。

主要问题是指针指向的对象会随着每次调用foo. 这对于多线程应用程序尤其危险。

于 2021-10-23T17:46:34.130 回答
0

在主函数中 z 不可访问,这就是它显示未定义行为的原因。您可以将 z 声明为全局变量,例如

#include <stdio.h>
int z =0;
int * sum_returning_pointer(int *x, int *y)
{
// Call be reference
z = (*x) + (*y);
 return &z;
 }

  void main(int *argc, char *argv[])
  {

   int a = 1, b = 2;
   int *p = sum_returning_pointer(&a, &b);
   printf("Sum = %d\n", *p);
   }
于 2021-10-23T17:13:10.333 回答