How to dereference the pointer returned by a function?

351 Views Asked by At
#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);
}

With the above function i'm trying to add up the two numbers which are passed as a reference to the called function and returning pointer pointing to the variable where sum is stored. But i'm getting weird error saying.

Error has occured.
Segmentation Fault.

What does this error mean? How can i achieve a solution ? Why does this error occurs ?

2

There are 2 best solutions below

0
rajnish kumar On BEST ANSWER

In main function z is not accessible that's why it is showing undefined behavior. You can declare z as a global variable like

#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);
   }
0
tstanisl On

The problem is not how to dereference but how to assure that the pointer is valid. In your code the address of a local variable is returned. This lifetime of this variable ends when program returns from the function. Dereferencing this pointer after that invokes Undefined Behavior.

Note, that typically small objects like int should be returned by value.

There are 3 generic strategies of returning a pointer to the result from a function.

  1. (IMO, the best) Let the caller handle the lifetime.
int *foo(const int *x, const int *y, int *z) {
  *z = *x + *y;
  return z;
}

Usage:

int x = 1, y = 2, z;
int *res = foo(&x, &y, &z);
  1. Use dynamic storage
int *foo(const int *x, const int *y) {
  int *z = malloc(sizeof *z);
  if (!z) {
    // complain
    return NULL;
  }
  *z = *x + *y;
  return z;
}

This solution tends to be very slow and error prone because the caller is responsible for freeing result.

  1. Use static.
int *foo(const int *x, const int *y) {
  static int z;
  z = *x + *y;
  return &z;
}

Works well because lifetime of a static variable extends for the whole execution of the program.

The main issue is that the object pointed by the pointer will change with every invocation of foo. That is especially dangerous for multi-threaded applications.